From aee016077249f08ae0f36ee4e00af17932d902cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 15 Jul 2025 13:34:30 -0300 Subject: [PATCH 001/116] chore: refactor x402 types, make it extensible to other schemes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/client/signPaymentHeader.ts | 4 +- .../x402/src/facilitator/facilitator.ts | 3 + .../x402/src/schemes/exact/evm/client.ts | 16 ++-- .../x402/src/schemes/exact/evm/facilitator.ts | 6 +- .../x402/src/schemes/exact/evm/sign.ts | 3 +- .../schemes/exact/evm/utils/paymentUtils.ts | 7 +- .../x402/src/types/verify/constants.ts | 6 ++ .../x402/src/types/verify/refiners.ts | 3 + .../x402/src/types/verify/schemes/exact.ts | 86 +++++++++++++++++++ .../x402/src/types/verify/x402Specs.ts | 86 ++++--------------- 10 files changed, 135 insertions(+), 85 deletions(-) create mode 100644 typescript/packages/x402/src/types/verify/constants.ts create mode 100644 typescript/packages/x402/src/types/verify/refiners.ts create mode 100644 typescript/packages/x402/src/types/verify/schemes/exact.ts diff --git a/typescript/packages/x402/src/client/signPaymentHeader.ts b/typescript/packages/x402/src/client/signPaymentHeader.ts index b28ae1de85..9dd0126831 100644 --- a/typescript/packages/x402/src/client/signPaymentHeader.ts +++ b/typescript/packages/x402/src/client/signPaymentHeader.ts @@ -2,6 +2,7 @@ import { signPaymentHeader as signPaymentHeaderExactEVM } from "../schemes/exact import { encodePayment } from "../schemes/exact/evm/utils/paymentUtils"; import { isEvmSignerWallet, isMultiNetworkSigner, MultiNetworkSigner, Signer, SupportedEVMNetworks } from "../types/shared"; import { PaymentRequirements, UnsignedPaymentPayload } from "../types/verify"; +import { UnsignedExactPaymentPayloadSchema } from "../types/verify/schemes/exact"; /** * Signs a payment header using the provided client and payment requirements. @@ -25,7 +26,8 @@ export async function signPaymentHeader( if (!isEvmSignerWallet(evmClient)) { throw new Error("Invalid evm wallet client provided"); } - const signedPaymentHeader = await signPaymentHeaderExactEVM(evmClient, paymentRequirements, unsignedPaymentHeader); + unsignedPaymentHeader = UnsignedExactPaymentPayloadSchema.parse(unsignedPaymentHeader); + const signedPaymentHeader = await signPaymentHeaderExactEVM(client, paymentRequirements, unsignedPaymentHeader); return encodePayment(signedPaymentHeader); } diff --git a/typescript/packages/x402/src/facilitator/facilitator.ts b/typescript/packages/x402/src/facilitator/facilitator.ts index 74af68cbba..f94459264d 100644 --- a/typescript/packages/x402/src/facilitator/facilitator.ts +++ b/typescript/packages/x402/src/facilitator/facilitator.ts @@ -15,6 +15,7 @@ import { } from "../types/verify"; import { Chain, Transport, Account } from "viem"; import { KeyPairSigner } from "@solana/kit"; +import { ExactPaymentPayloadSchema } from "../types/verify/schemes/exact"; /** * Verifies a payment payload against the required payment details regardless of the scheme @@ -36,6 +37,7 @@ export async function verify< ): Promise { // exact scheme if (paymentRequirements.scheme === "exact") { + payload = ExactPaymentPayloadSchema.parse(payload); // evm if (SupportedEVMNetworks.includes(paymentRequirements.network)) { return verifyExactEvm( @@ -77,6 +79,7 @@ export async function settle( ): Promise { // exact scheme if (paymentRequirements.scheme === "exact") { + payload = ExactPaymentPayloadSchema.parse(payload); // evm if (SupportedEVMNetworks.includes(paymentRequirements.network)) { return await settleExactEvm( diff --git a/typescript/packages/x402/src/schemes/exact/evm/client.ts b/typescript/packages/x402/src/schemes/exact/evm/client.ts index 771e51a60d..d5dbd9825e 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/client.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/client.ts @@ -1,8 +1,12 @@ import { Address, Chain, LocalAccount, Transport } from "viem"; import { isSignerWallet, SignerWallet } from "../../../types/shared/evm"; -import { PaymentPayload, PaymentRequirements, UnsignedPaymentPayload } from "../../../types/verify"; +import { PaymentRequirements } from "../../../types/verify"; import { createNonce, signAuthorization } from "./sign"; import { encodePayment } from "./utils/paymentUtils"; +import { + ExactPaymentPayload, + UnsignedExactPaymentPayload, +} from "../../../types/verify/schemes/exact"; /** * Prepares an unsigned payment header with the given sender address and payment requirements. @@ -16,7 +20,7 @@ export function preparePaymentHeader( from: Address, x402Version: number, paymentRequirements: PaymentRequirements, -): UnsignedPaymentPayload { +): UnsignedExactPaymentPayload { const nonce = createNonce(); const validAfter = BigInt( @@ -28,7 +32,7 @@ export function preparePaymentHeader( return { x402Version, - scheme: paymentRequirements.scheme, + scheme: "exact", network: paymentRequirements.network, payload: { signature: undefined, @@ -55,8 +59,8 @@ export function preparePaymentHeader( export async function signPaymentHeader( client: SignerWallet | LocalAccount, paymentRequirements: PaymentRequirements, - unsignedPaymentHeader: UnsignedPaymentPayload, -): Promise { + unsignedPaymentHeader: UnsignedExactPaymentPayload, +): Promise { const { signature } = await signAuthorization( client, unsignedPaymentHeader.payload.authorization, @@ -84,7 +88,7 @@ export async function createPayment | LocalAccount, x402Version: number, paymentRequirements: PaymentRequirements, -): Promise { +): Promise { const from = isSignerWallet(client) ? client.account!.address : client.address; const unsignedPaymentHeader = preparePaymentHeader(from, x402Version, paymentRequirements); return signPaymentHeader(client, paymentRequirements, unsignedPaymentHeader); diff --git a/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts b/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts index fd8a1647fa..88798dcf41 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts @@ -9,13 +9,13 @@ import { SignerWallet, } from "../../../types/shared/evm"; import { - PaymentPayload, PaymentRequirements, SettleResponse, VerifyResponse, ExactEvmPayload, } from "../../../types/verify"; import { SCHEME } from "../../exact"; +import { ExactPaymentPayload } from "../../../types/verify/schemes/exact"; /** * Verifies a payment payload against the required payment details @@ -39,7 +39,7 @@ export async function verify< account extends Account | undefined, >( client: ConnectedClient, - payload: PaymentPayload, + payload: ExactPaymentPayload, paymentRequirements: PaymentRequirements, ): Promise { /* TODO: work with security team on brainstorming more verification steps @@ -183,7 +183,7 @@ export async function verify< */ export async function settle( wallet: SignerWallet, - paymentPayload: PaymentPayload, + paymentPayload: ExactPaymentPayload, paymentRequirements: PaymentRequirements, ): Promise { const payload = paymentPayload.payload as ExactEvmPayload; diff --git a/typescript/packages/x402/src/schemes/exact/evm/sign.ts b/typescript/packages/x402/src/schemes/exact/evm/sign.ts index b7d72af4a0..726197b3cc 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/sign.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/sign.ts @@ -6,7 +6,8 @@ import { isSignerWallet, SignerWallet, } from "../../../types/shared/evm"; -import { ExactEvmPayloadAuthorization, PaymentRequirements } from "../../../types/verify"; +import { PaymentRequirements } from "../../../types/verify"; +import { ExactEvmPayloadAuthorization } from "../../../types/verify/schemes/exact"; /** * Signs an EIP-3009 authorization for USDC transfer diff --git a/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts b/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts index 6d0727a3b9..4042536968 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts @@ -2,9 +2,10 @@ import { safeBase64Encode, safeBase64Decode } from "../../../../shared"; import { SupportedEVMNetworks, SupportedSVMNetworks } from "../../../../types"; import { PaymentPayload, - PaymentPayloadSchema, ExactEvmPayload, ExactSvmPayload, + ExactPaymentPayload, + ExactPaymentPayloadSchema, } from "../../../../types/verify"; /** @@ -49,7 +50,7 @@ export function encodePayment(payment: PaymentPayload): string { * @param payment - The base64 encoded payment string to decode * @returns The decoded and validated PaymentPayload object */ -export function decodePayment(payment: string): PaymentPayload { +export function decodePayment(payment: string): ExactPaymentPayload { const decoded = safeBase64Decode(payment); const parsed = JSON.parse(decoded); @@ -73,6 +74,6 @@ export function decodePayment(payment: string): PaymentPayload { throw new Error("Invalid network"); } - const validated = PaymentPayloadSchema.parse(obj); + const validated = ExactPaymentPayloadSchema.parse(obj); return validated; } diff --git a/typescript/packages/x402/src/types/verify/constants.ts b/typescript/packages/x402/src/types/verify/constants.ts new file mode 100644 index 0000000000..d39821e6db --- /dev/null +++ b/typescript/packages/x402/src/types/verify/constants.ts @@ -0,0 +1,6 @@ +// Constants +export const EvmMaxAtomicUnits = 18; +export const EvmAddressRegex = /^0x[0-9a-fA-F]{40}$/; +export const MixedAddressRegex = /^0x[a-fA-F0-9]{40}|[A-Za-z0-9][A-Za-z0-9-]{0,34}[A-Za-z0-9]$/; +export const HexEncoded64ByteRegex = /^0x[0-9a-fA-F]{64}$/; +export const EvmSignatureRegex = /^0x[0-9a-fA-F]+$/; // Flexible hex signature validation diff --git a/typescript/packages/x402/src/types/verify/refiners.ts b/typescript/packages/x402/src/types/verify/refiners.ts new file mode 100644 index 0000000000..3846c41786 --- /dev/null +++ b/typescript/packages/x402/src/types/verify/refiners.ts @@ -0,0 +1,3 @@ +// Refiners +export const isInteger = (value: string) => Number.isInteger(Number(value)) && Number(value) >= 0; +export const hasMaxLength = (maxLength: number) => (value: string) => value.length <= maxLength; diff --git a/typescript/packages/x402/src/types/verify/schemes/exact.ts b/typescript/packages/x402/src/types/verify/schemes/exact.ts new file mode 100644 index 0000000000..81a8174498 --- /dev/null +++ b/typescript/packages/x402/src/types/verify/schemes/exact.ts @@ -0,0 +1,86 @@ +import { z } from "zod"; +import { + EvmAddressRegex, + EvmSignatureRegex, + HexEncoded64ByteRegex, + EvmMaxAtomicUnits, +} from "../constants"; +import { hasMaxLength, isInteger } from "../refiners"; +import { NetworkSchema, x402Versions } from "../.."; +import { Base64EncodedRegex } from "../../../shared"; + +export const ExactErrorReasons = [ + "invalid_exact_evm_payload_authorization_valid_after", + "invalid_exact_evm_payload_authorization_valid_before", + "invalid_exact_evm_payload_authorization_value", + "invalid_exact_evm_payload_signature", + "invalid_exact_evm_payload_recipient_mismatch", + "invalid_exact_evm_payload_from_mismatch", + "invalid_exact_evm_payload_to_mismatch", + "invalid_exact_evm_payload_value_mismatch", + "invalid_exact_evm_payload_valid_after_mismatch", + "invalid_exact_evm_payload_valid_before_mismatch", + "invalid_exact_evm_payload_nonce_mismatch", + "invalid_exact_svm_payload_transaction", + "invalid_exact_svm_payload_transaction_amount_mismatch", + "invalid_exact_svm_payload_transaction_create_ata_instruction", + "invalid_exact_svm_payload_transaction_create_ata_instruction_incorrect_payee", + "invalid_exact_svm_payload_transaction_create_ata_instruction_incorrect_asset", + "invalid_exact_svm_payload_transaction_instructions", + "invalid_exact_svm_payload_transaction_instructions_length", + "invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction", + "invalid_exact_svm_payload_transaction_instructions_compute_price_instruction", + "invalid_exact_svm_payload_transaction_instructions_compute_price_instruction_too_high", + "invalid_exact_svm_payload_transaction_instruction_not_spl_token_transfer_checked", + "invalid_exact_svm_payload_transaction_instruction_not_token_2022_transfer_checked", + "invalid_exact_svm_payload_transaction_not_a_transfer_instruction", + "invalid_exact_svm_payload_transaction_cannot_derive_receiver_ata", + "invalid_exact_svm_payload_transaction_receiver_ata_not_found", + "invalid_exact_svm_payload_transaction_sender_ata_not_found", + "invalid_exact_svm_payload_transaction_simulation_failed", + "invalid_exact_svm_payload_transaction_transfer_to_incorrect_ata", +] as const; + +// x402ExactEvmPayloadAuthorization +export const ExactEvmPayloadAuthorizationSchema = z.object({ + from: z.string().regex(EvmAddressRegex), + to: z.string().regex(EvmAddressRegex), + value: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + validAfter: z.string().refine(isInteger), + validBefore: z.string().refine(isInteger), + nonce: z.string().regex(HexEncoded64ByteRegex), +}); +export type ExactEvmPayloadAuthorization = z.infer; + +// x402ExactEvmPayload +export const ExactEvmPayloadSchema = z.object({ + signature: z.string().regex(EvmSignatureRegex), + authorization: ExactEvmPayloadAuthorizationSchema, +}); +export type ExactEvmPayload = z.infer; + +// x402ExactSvmPayload +export const ExactSvmPayloadSchema = z.object({ + transaction: z.string().regex(Base64EncodedRegex), +}); +export type ExactSvmPayload = z.infer; + +// x402ExactPaymentPayload +export const ExactPaymentPayloadSchema = z.object({ + x402Version: z.number().refine(val => x402Versions.includes(val as 1)), + scheme: z.literal("exact"), + network: NetworkSchema, + payload: z.union([ExactEvmPayloadSchema, ExactSvmPayloadSchema]), +}); +export type ExactPaymentPayload = z.infer; + +// x402UnsignedPaymentPayload +export const UnsignedExactPaymentPayloadSchema = z.object({ + x402Version: z.number().refine(val => x402Versions.includes(val as 1)), + scheme: z.literal("exact"), + network: NetworkSchema, + payload: ExactEvmPayloadSchema.omit({ signature: true }).extend({ + signature: z.undefined(), + }), +}); +export type UnsignedExactPaymentPayload = z.infer; diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index 2b6c14461b..4642f91ef1 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -1,42 +1,19 @@ import { z } from "zod"; import { NetworkSchema } from "../shared"; import { SvmAddressRegex } from "../shared/svm"; -import { Base64EncodedRegex } from "../../shared/base64"; - -// Constants -const EvmMaxAtomicUnits = 18; -const EvmAddressRegex = /^0x[0-9a-fA-F]{40}$/; -const MixedAddressRegex = /^0x[a-fA-F0-9]{40}|[A-Za-z0-9][A-Za-z0-9-]{0,34}[A-Za-z0-9]$/; -const HexEncoded64ByteRegex = /^0x[0-9a-fA-F]{64}$/; -const EvmSignatureRegex = /^0x[0-9a-fA-F]+$/; // Flexible hex signature validation +import { isInteger } from "./refiners"; +import { EvmAddressRegex, MixedAddressRegex } from "./constants"; +import { + ExactErrorReasons, + ExactPaymentPayloadSchema, + UnsignedExactPaymentPayloadSchema, +} from "./schemes/exact"; + // Enums -export const schemes = ["exact"] as const; +export const schemes = ["exact", "deferred"] as const; export const x402Versions = [1] as const; export const ErrorReasons = [ "insufficient_funds", - "invalid_exact_evm_payload_authorization_valid_after", - "invalid_exact_evm_payload_authorization_valid_before", - "invalid_exact_evm_payload_authorization_value", - "invalid_exact_evm_payload_signature", - "invalid_exact_evm_payload_recipient_mismatch", - "invalid_exact_svm_payload_transaction", - "invalid_exact_svm_payload_transaction_amount_mismatch", - "invalid_exact_svm_payload_transaction_create_ata_instruction", - "invalid_exact_svm_payload_transaction_create_ata_instruction_incorrect_payee", - "invalid_exact_svm_payload_transaction_create_ata_instruction_incorrect_asset", - "invalid_exact_svm_payload_transaction_instructions", - "invalid_exact_svm_payload_transaction_instructions_length", - "invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction", - "invalid_exact_svm_payload_transaction_instructions_compute_price_instruction", - "invalid_exact_svm_payload_transaction_instructions_compute_price_instruction_too_high", - "invalid_exact_svm_payload_transaction_instruction_not_spl_token_transfer_checked", - "invalid_exact_svm_payload_transaction_instruction_not_token_2022_transfer_checked", - "invalid_exact_svm_payload_transaction_not_a_transfer_instruction", - "invalid_exact_svm_payload_transaction_cannot_derive_receiver_ata", - "invalid_exact_svm_payload_transaction_receiver_ata_not_found", - "invalid_exact_svm_payload_transaction_sender_ata_not_found", - "invalid_exact_svm_payload_transaction_simulation_failed", - "invalid_exact_svm_payload_transaction_transfer_to_incorrect_ata", "invalid_network", "invalid_payload", "invalid_payment_requirements", @@ -47,18 +24,12 @@ export const ErrorReasons = [ "invalid_x402_version", "invalid_transaction_state", "invalid_x402_version", - "settle_exact_svm_block_height_exceeded", - "settle_exact_svm_transaction_confirmation_timed_out", "unsupported_scheme", "unexpected_settle_error", "unexpected_verify_error", + ...ExactErrorReasons, ] as const; -// Refiners -const isInteger: (value: string) => boolean = value => - Number.isInteger(Number(value)) && Number(value) >= 0; -const hasMaxLength = (maxLength: number) => (value: string) => value.length <= maxLength; - // x402PaymentRequirements const EvmOrSvmAddress = z.string().regex(EvmAddressRegex).or(z.string().regex(SvmAddressRegex)); const mixedAddressOrSvmAddress = z @@ -80,40 +51,13 @@ export const PaymentRequirementsSchema = z.object({ }); export type PaymentRequirements = z.infer; -// x402ExactEvmPayload -export const ExactEvmPayloadAuthorizationSchema = z.object({ - from: z.string().regex(EvmAddressRegex), - to: z.string().regex(EvmAddressRegex), - value: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), - validAfter: z.string().refine(isInteger), - validBefore: z.string().refine(isInteger), - nonce: z.string().regex(HexEncoded64ByteRegex), -}); -export type ExactEvmPayloadAuthorization = z.infer; - -export const ExactEvmPayloadSchema = z.object({ - signature: z.string().regex(EvmSignatureRegex), - authorization: ExactEvmPayloadAuthorizationSchema, -}); -export type ExactEvmPayload = z.infer; - -// x402ExactSvmPayload -export const ExactSvmPayloadSchema = z.object({ - transaction: z.string().regex(Base64EncodedRegex), -}); -export type ExactSvmPayload = z.infer; - // x402PaymentPayload -export const PaymentPayloadSchema = z.object({ - x402Version: z.number().refine(val => x402Versions.includes(val as 1)), - scheme: z.enum(schemes), - network: NetworkSchema, - payload: z.union([ExactEvmPayloadSchema, ExactSvmPayloadSchema]), -}); +export const PaymentPayloadSchema = z.discriminatedUnion("scheme", [ExactPaymentPayloadSchema]); export type PaymentPayload = z.infer; -export type UnsignedPaymentPayload = Omit & { - payload: Omit & { signature: undefined }; -}; +export const UnsignedPaymentPayloadSchema = z.discriminatedUnion("scheme", [ + UnsignedExactPaymentPayloadSchema, +]); +export type UnsignedPaymentPayload = z.infer; // x402 Resource Server Response export const x402ResponseSchema = z.object({ From 9ab233158c0b772d2b0efc09b132e46da75788b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 15 Jul 2025 18:00:52 -0300 Subject: [PATCH 002/116] wip: implement deferred scheme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/facilitator/facilitator.ts | 18 ++ .../src/schemes/deferred/evm/client.test.ts | 282 ++++++++++++++++++ .../x402/src/schemes/deferred/evm/client.ts | 112 +++++++ .../src/schemes/deferred/evm/facilitator.ts | 240 +++++++++++++++ .../x402/src/schemes/deferred/evm/index.ts | 3 + .../x402/src/schemes/deferred/evm/sign.ts | 70 +++++ .../deferred/evm/utils/paymentUtils.ts | 54 ++++ .../x402/src/schemes/deferred/index.ts | 3 + .../x402/src/schemes/exact/evm/facilitator.ts | 7 +- .../src/types/shared/evm/deferredEscrowABI.ts | 21 ++ .../x402/src/types/shared/evm/eip3009.ts | 12 - .../x402/src/types/shared/evm/typedData.ts | 24 ++ .../x402/src/types/verify/schemes/deferred.ts | 59 ++++ .../x402/src/types/verify/x402Specs.ts | 12 +- 14 files changed, 901 insertions(+), 16 deletions(-) create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/client.test.ts create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/client.ts create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/index.ts create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/sign.ts create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts create mode 100644 typescript/packages/x402/src/schemes/deferred/index.ts create mode 100644 typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts delete mode 100644 typescript/packages/x402/src/types/shared/evm/eip3009.ts create mode 100644 typescript/packages/x402/src/types/shared/evm/typedData.ts create mode 100644 typescript/packages/x402/src/types/verify/schemes/deferred.ts diff --git a/typescript/packages/x402/src/facilitator/facilitator.ts b/typescript/packages/x402/src/facilitator/facilitator.ts index f94459264d..0fc6164b2d 100644 --- a/typescript/packages/x402/src/facilitator/facilitator.ts +++ b/typescript/packages/x402/src/facilitator/facilitator.ts @@ -16,6 +16,7 @@ import { import { Chain, Transport, Account } from "viem"; import { KeyPairSigner } from "@solana/kit"; import { ExactPaymentPayloadSchema } from "../types/verify/schemes/exact"; +import { DeferredPaymentPayloadSchema } from "../types/verify/schemes/deferred"; /** * Verifies a payment payload against the required payment details regardless of the scheme @@ -53,7 +54,24 @@ export async function verify< } } +<<<<<<< HEAD // unsupported scheme +======= + if (paymentRequirements.scheme == "deferred") { + payload = DeferredPaymentPayloadSchema.parse(payload); + if (SupportedEVMNetworks.includes(paymentRequirements.network)) { + const valid = await verifyDeferred(client, payload, paymentRequirements); + return valid; + } else { + return { + isValid: false, + invalidReason: "invalid_scheme", + payer: payload.payload.voucher.buyer, + }; + } + } + +>>>>>>> 69d9ed0 (wip: implement deferred scheme) return { isValid: false, invalidReason: "invalid_scheme", diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts new file mode 100644 index 0000000000..02527309fd --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -0,0 +1,282 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { createSignerSepolia, SignerWallet } from "../../../types/shared/evm"; +import { PaymentRequirements, UnsignedPaymentPayload } from "../../../types/verify"; +import { createPaymentHeader, preparePaymentHeader, signPaymentHeader } from "./client"; +import { signAuthorization } from "./sign"; +import { encodePayment } from "./utils/paymentUtils"; + +vi.mock("./sign", async () => { + const actual = await vi.importActual("./sign"); + return { + ...actual, + signAuthorization: vi.fn(), + }; +}); + +vi.mock("./utils/paymentUtils", () => ({ + encodePayment: vi.fn().mockReturnValue("encoded-payment-header"), +})); + +describe("preparePaymentHeader", () => { + const mockPaymentRequirements: PaymentRequirements = { + scheme: "exact", + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test resource", + mimeType: "application/json", + payTo: "0x1234567890123456789012345678901234567890", + maxTimeoutSeconds: 300, + asset: "0x1234567890123456789012345678901234567890", + }; + + const mockFromAddress = "0xabcdef1234567890123456789012345678901234"; + + beforeEach(() => { + vi.useFakeTimers(); + // Set a fixed time for consistent testing + vi.setSystemTime(new Date("2024-01-01T00:00:00Z")); + vi.clearAllMocks(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it("should create a valid unsigned payment header", () => { + const result = preparePaymentHeader(mockFromAddress, 1, mockPaymentRequirements); + const currentTime = Math.floor(Date.now() / 1000); + + expect(result).toEqual({ + x402Version: 1, + scheme: "exact", + network: "base-sepolia", + payload: { + signature: undefined, + authorization: { + from: mockFromAddress, + to: mockPaymentRequirements.payTo, + value: mockPaymentRequirements.maxAmountRequired, + validAfter: (currentTime - 600).toString(), + validBefore: (currentTime + mockPaymentRequirements.maxTimeoutSeconds).toString(), + nonce: expect.any(String), + }, + }, + }); + }); + + it("should generate a unique nonce for each call", () => { + const result1 = preparePaymentHeader(mockFromAddress, 1, mockPaymentRequirements); + const result2 = preparePaymentHeader(mockFromAddress, 1, mockPaymentRequirements); + + expect(result1.payload.authorization.nonce.length).toBe(66); + expect(result2.payload.authorization.nonce.length).toBe(66); + expect(result1.payload.authorization.nonce).not.toBe(result2.payload.authorization.nonce); + }); + + it("should calculate validAfter as 60 seconds before current time", () => { + const result = preparePaymentHeader(mockFromAddress, 1, mockPaymentRequirements); + const currentTime = Math.floor(Date.now() / 1000); + const validAfter = parseInt(result.payload.authorization.validAfter); + + expect(validAfter).toBe(currentTime - 600); + }); + + it("should calculate validBefore as current time plus maxTimeoutSeconds", () => { + const result = preparePaymentHeader(mockFromAddress, 1, mockPaymentRequirements); + const currentTime = Math.floor(Date.now() / 1000); + const validBefore = parseInt(result.payload.authorization.validBefore); + + expect(validBefore).toBe(currentTime + mockPaymentRequirements.maxTimeoutSeconds); + }); + + it("should handle different x402 versions", () => { + const result = preparePaymentHeader(mockFromAddress, 2, mockPaymentRequirements); + expect(result.x402Version).toBe(2); + }); +}); + +describe("signPaymentHeader", () => { + const mockPaymentRequirements: PaymentRequirements = { + scheme: "exact", + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test resource", + mimeType: "application/json", + payTo: "0x1234567890123456789012345678901234567890", + maxTimeoutSeconds: 300, + asset: "0x1234567890123456789012345678901234567890", + }; + + const mockUnsignedHeader: UnsignedPaymentPayload = { + x402Version: 1, + scheme: "exact", + network: "base-sepolia", + payload: { + signature: undefined, + authorization: { + from: "0xabcdef1234567890123456789012345678901234", + to: "0x1234567890123456789012345678901234567890", + value: "1000000", + validAfter: "1704067195", + validBefore: "1704067495", + nonce: "1234567890", + }, + }, + }; + + const mockSignature = "0x1234567890123456789012345678901234567890123456789012345678901234"; + + const createTestClient = () => { + return createSignerSepolia( + "0x1234567890123456789012345678901234567890123456789012345678901234", + ); + }; + + beforeEach(() => { + vi.clearAllMocks(); + vi.mocked(signAuthorization).mockResolvedValue({ signature: mockSignature }); + }); + + it("should sign the payment header and return a complete payload", async () => { + const client = createTestClient(); + const result = await signPaymentHeader(client, mockPaymentRequirements, mockUnsignedHeader); + + expect(signAuthorization).toHaveBeenCalledWith( + client, + mockUnsignedHeader.payload.authorization, + mockPaymentRequirements, + ); + + expect(result).toEqual({ + ...mockUnsignedHeader, + payload: { + ...mockUnsignedHeader.payload, + signature: mockSignature, + }, + }); + }); + + it("should preserve all original fields in the signed payload", async () => { + const client = createTestClient(); + const result = await signPaymentHeader(client, mockPaymentRequirements, mockUnsignedHeader); + + // Check that all original fields are preserved + expect(result.x402Version).toBe(mockUnsignedHeader.x402Version); + expect(result.scheme).toBe(mockUnsignedHeader.scheme); + expect(result.network).toBe(mockUnsignedHeader.network); + expect(result.payload.authorization).toEqual(mockUnsignedHeader.payload.authorization); + }); + + it("should throw an error if signing fails", async () => { + const client = createTestClient(); + const error = new Error("Signing failed"); + vi.mocked(signAuthorization).mockRejectedValue(error); + + await expect( + signPaymentHeader(client, mockPaymentRequirements, mockUnsignedHeader), + ).rejects.toThrow("Signing failed"); + }); +}); + +describe("createPaymentHeader", () => { + const mockPaymentRequirements: PaymentRequirements = { + scheme: "exact", + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test resource", + mimeType: "application/json", + payTo: "0x1234567890123456789012345678901234567890", + maxTimeoutSeconds: 300, + asset: "0x1234567890123456789012345678901234567890", + }; + + const mockSignedPayment = { + x402Version: 1, + scheme: "exact", + network: "base-sepolia", + payload: { + signature: + "0x1234567890123456789012345678901234567890123456789012345678901234" as `0x${string}`, + authorization: { + from: "0xabcdef1234567890123456789012345678901234" as `0x${string}`, + to: "0x1234567890123456789012345678901234567890" as `0x${string}`, + value: "1000000", + validAfter: "1704067195", + validBefore: "1704067495", + nonce: "1234567890", + }, + }, + }; + + const createTestClient = () => { + const client = createSignerSepolia( + "0x1234567890123456789012345678901234567890123456789012345678901234" as `0x${string}`, + ); + return client as unknown as SignerWallet; + }; + + beforeEach(() => { + vi.clearAllMocks(); + vi.mocked(signAuthorization).mockResolvedValue({ + signature: mockSignedPayment.payload.signature, + }); + }); + + it("should create and encode a payment header", async () => { + const client = createTestClient(); + const result = await createPaymentHeader(client, 1, mockPaymentRequirements); + + expect(result).toBe("encoded-payment-header"); + expect(vi.mocked(encodePayment)).toHaveBeenCalledWith( + expect.objectContaining({ + x402Version: 1, + scheme: "exact", + network: "base-sepolia", + payload: expect.objectContaining({ + signature: mockSignedPayment.payload.signature, + authorization: expect.objectContaining({ + from: client.account!.address, + to: mockPaymentRequirements.payTo, + value: mockPaymentRequirements.maxAmountRequired, + }), + }), + }), + ); + }); + + it("should handle different x402 versions", async () => { + const client = createTestClient(); + await createPaymentHeader(client, 2, mockPaymentRequirements); + + expect(vi.mocked(encodePayment)).toHaveBeenCalledWith( + expect.objectContaining({ + x402Version: 2, + }), + ); + }); + + it("should throw an error if signing fails", async () => { + const client = createTestClient(); + const error = new Error("Signing failed"); + vi.mocked(signAuthorization).mockRejectedValue(error); + + await expect(createPaymentHeader(client, 1, mockPaymentRequirements)).rejects.toThrow( + "Signing failed", + ); + }); + + it("should throw an error if encoding fails", async () => { + const client = createTestClient(); + const error = new Error("Encoding failed"); + vi.mocked(encodePayment).mockImplementation(() => { + throw error; + }); + + await expect(createPaymentHeader(client, 1, mockPaymentRequirements)).rejects.toThrow( + "Encoding failed", + ); + }); +}); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts new file mode 100644 index 0000000000..d5dbd9825e --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -0,0 +1,112 @@ +import { Address, Chain, LocalAccount, Transport } from "viem"; +import { isSignerWallet, SignerWallet } from "../../../types/shared/evm"; +import { PaymentRequirements } from "../../../types/verify"; +import { createNonce, signAuthorization } from "./sign"; +import { encodePayment } from "./utils/paymentUtils"; +import { + ExactPaymentPayload, + UnsignedExactPaymentPayload, +} from "../../../types/verify/schemes/exact"; + +/** + * 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 + */ +export function preparePaymentHeader( + from: Address, + x402Version: number, + paymentRequirements: PaymentRequirements, +): UnsignedExactPaymentPayload { + 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: "exact", + 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 + */ +export async function signPaymentHeader( + client: SignerWallet | LocalAccount, + paymentRequirements: PaymentRequirements, + unsignedPaymentHeader: UnsignedExactPaymentPayload, +): Promise { + const { signature } = await signAuthorization( + client, + 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 + */ +export async function createPayment( + client: SignerWallet | LocalAccount, + x402Version: number, + paymentRequirements: PaymentRequirements, +): Promise { + const from = isSignerWallet(client) ? client.account!.address : client.address; + const unsignedPaymentHeader = preparePaymentHeader(from, x402Version, paymentRequirements); + return signPaymentHeader(client, 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( + client: SignerWallet | LocalAccount, + x402Version: number, + paymentRequirements: PaymentRequirements, +): Promise { + const payment = await createPayment(client, x402Version, paymentRequirements); + return encodePayment(payment); +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts new file mode 100644 index 0000000000..70a4e8c14c --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -0,0 +1,240 @@ +import { Account, Address, Chain, getAddress, Hex, parseErc6492Signature, Transport } from "viem"; +import { getNetworkId } from "../../../shared"; +import { getERC20Balance } from "../../../shared/evm"; +import { + usdcABI as abi, + typedDataTypes, + ConnectedClient, + SignerWallet, + deferredVoucherPrimaryType, +} from "../../../types/shared/evm"; +import { PaymentRequirements, SettleResponse, VerifyResponse } from "../../../types/verify"; +import { SCHEME } from "../../deferred"; +import { DeferredPaymentPayload } from "../../../types/verify/schemes/deferred"; +import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; + +/** + * Verifies a payment payload against the required payment details + * + * This function performs several verification steps: + * - ✅ Verify payload matches requirements + * - ✅ Verify scheme is deferred + * - ✅ Verify network matches payment requirements + * - ✅ Verify voucher value is enough to cover maxAmountRequired + * - ✅ Verify payTo is voucher seller + * - ✅ Verify voucher asset matches payment requirements + * - ✅ Validates the signature is valid + * - ✅ Validates the voucher chainId matches the chain specified in the payment requirements + * - ✅ (on-chain) Verifies buyer has sufficient asset balance + * - ✅ (on-chain) Verifies the voucher id has not been already claimed + * + * @param client - The public client used for blockchain interactions + * @param payload - The signed payment payload containing transfer parameters and signature + * @param paymentRequirements - The payment requirements that the payload must satisfy + * @returns A ValidPaymentRequest indicating if the payment is valid and any invalidation reason + */ +export async function verify< + transport extends Transport, + chain extends Chain, + account extends Account | undefined, +>( + client: ConnectedClient, + payload: DeferredPaymentPayload, + paymentRequirements: PaymentRequirements, +): Promise { + // Verify payload matches requirements: scheme + if (payload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) { + return { + isValid: false, + invalidReason: `unsupported_scheme`, + payer: payload.payload.voucher.buyer, + }; + } + + // Verify payload matches requirements: network + if (payload.network !== paymentRequirements.network) { + return { + isValid: false, + invalidReason: `invalid_network`, + payer: payload.payload.voucher.buyer, + }; + } + + // Verify payload matches requirements: maxAmountRequired -- value in payload is enough to cover paymentRequirements.maxAmountRequired + if (BigInt(payload.payload.voucher.value) < BigInt(paymentRequirements.maxAmountRequired)) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_value", + payer: payload.payload.voucher.buyer, + }; + } + + // Verify payload matches requirements: payTo + if (getAddress(payload.payload.voucher.seller) !== getAddress(paymentRequirements.payTo)) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_recipient_mismatch", + payer: payload.payload.voucher.buyer, + }; + } + + // Verify payload matches requirements: asset + if (payload.payload.voucher.asset !== paymentRequirements.asset) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_asset_mismatch", + payer: payload.payload.voucher.buyer, + }; + } + + //Validates the voucher chainId matches the chain specified in the payment requirements + let chainId: number; + try { + chainId = getNetworkId(paymentRequirements.network); + if (chainId !== payload.payload.voucher.chainId) { + throw new Error(); + } + } catch { + return { + isValid: false, + invalidReason: `invalid_deferred_evm_payload_chain_id`, + payer: payload.payload.voucher.buyer, + }; + } + + // Verify voucher signature is recoverable for the owner address + const voucherTypedData = { + types: typedDataTypes, + primaryType: deferredVoucherPrimaryType, + domain: { + name: "VoucherEscrow", + version: "1", + chainId, + verifyingContract: payload.payload.voucher.escrow as Address, + }, + message: payload.payload.voucher, + }; + const recoveredAddress = await client.verifyTypedData({ + address: payload.payload.voucher.buyer as Address, + ...voucherTypedData, + signature: payload.payload.signature as Hex, + }); + if (!recoveredAddress) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_signature", + payer: payload.payload.voucher.buyer, + }; + } + + // Verify buyer has sufficient asset balance + try { + const balance = await getERC20Balance( + client, + payload.payload.voucher.asset as Address, + payload.payload.voucher.buyer as Address, + ); + if (balance < BigInt(payload.payload.voucher.value)) { + throw new Error(); + } + } catch { + return { + isValid: false, + invalidReason: "insufficient_funds", + payer: payload.payload.voucher.buyer, + }; + } + + // Verify voucher id has not been already claimed + try { + const isCollected = await client.readContract({ + address: payload.payload.voucher.escrow as Address, + abi: deferredEscrowABI, + functionName: "isCollected", + args: [payload.payload.voucher.id as Hex], + }); + if (isCollected) { + throw new Error(); + } + } catch { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_already_claimed", + payer: payload.payload.voucher.buyer, + }; + } + + return { + isValid: true, + invalidReason: undefined, + payer: payload.payload.voucher.buyer, + }; +} + +/** + * Settles a payment by executing a USDC transferWithAuthorization transaction + * + * This function executes the actual USDC transfer using the signed authorization from the user. + * The facilitator wallet submits the transaction but does not need to hold or transfer any tokens itself. + * + * @param wallet - The facilitator wallet that will submit the transaction + * @param paymentPayload - The signed payment payload containing the transfer parameters and signature + * @param paymentRequirements - The original payment details that were used to create the payload + * @returns A PaymentExecutionResponse containing the transaction status and hash + */ +export async function settle( + wallet: SignerWallet, + paymentPayload: ExactPaymentPayload, + paymentRequirements: PaymentRequirements, +): Promise { + // re-verify to ensure the payment is still valid + const valid = await verify(wallet, paymentPayload, paymentRequirements); + + if (!valid.isValid) { + return { + success: false, + network: paymentPayload.network, + transaction: "", + errorReason: valid.invalidReason ?? "invalid_scheme", //`Payment is no longer valid: ${valid.invalidReason}`, + payer: paymentPayload.payload.authorization.from, + }; + } + + // Returns the original signature (no-op) if the signature is not a 6492 signature + const { signature } = parseErc6492Signature(paymentPayload.payload.signature as Hex); + + const tx = await wallet.writeContract({ + address: paymentRequirements.asset as Address, + abi, + functionName: "transferWithAuthorization" as const, + args: [ + paymentPayload.payload.authorization.from as Address, + paymentPayload.payload.authorization.to as Address, + BigInt(paymentPayload.payload.authorization.value), + BigInt(paymentPayload.payload.authorization.validAfter), + BigInt(paymentPayload.payload.authorization.validBefore), + paymentPayload.payload.authorization.nonce as Hex, + signature, + ], + chain: wallet.chain as Chain, + }); + + const receipt = await wallet.waitForTransactionReceipt({ hash: tx }); + + if (receipt.status !== "success") { + return { + success: false, + errorReason: "invalid_transaction_state", //`Transaction failed`, + transaction: tx, + network: paymentPayload.network, + payer: paymentPayload.payload.authorization.from, + }; + } + + return { + success: true, + transaction: tx, + network: paymentPayload.network, + payer: paymentPayload.payload.authorization.from, + }; +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/index.ts b/typescript/packages/x402/src/schemes/deferred/evm/index.ts new file mode 100644 index 0000000000..2f115c892b --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/index.ts @@ -0,0 +1,3 @@ +export * from "./client"; +export * from "./facilitator"; +export * from "./utils/paymentUtils"; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts new file mode 100644 index 0000000000..2d681f482e --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts @@ -0,0 +1,70 @@ +import { Chain, getAddress, Hex, LocalAccount, toHex, Transport } from "viem"; +import { getNetworkId } from "../../../shared"; +import { + authorizationTypes, + isAccount, + isSignerWallet, + SignerWallet, +} from "../../../types/shared/evm"; +import { PaymentRequirements } from "../../../types/verify"; +import { ExactEvmPayloadAuthorization } from "../../../types/verify/schemes/exact"; + +/** + * 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 + */ +export async function signAuthorization( + walletClient: SignerWallet | LocalAccount, + { from, to, value, validAfter, validBefore, nonce }: ExactEvmPayloadAuthorization, + { asset, network, extra }: PaymentRequirements, +): Promise<{ signature: Hex }> { + const chainId = getNetworkId(network); + const name = extra?.name; + const version = extra?.version; + + const data = { + types: authorizationTypes, + domain: { + name, + version, + chainId, + verifyingContract: getAddress(asset), + }, + primaryType: "TransferWithAuthorization" as const, + message: { + from: getAddress(from), + to: getAddress(to), + value, + validAfter, + validBefore, + nonce: nonce, + }, + }; + + if (isSignerWallet(walletClient)) { + const signature = await walletClient.signTypedData(data); + return { + signature, + }; + } else if (isAccount(walletClient) && walletClient.signTypedData) { + const signature = await walletClient.signTypedData(data); + return { + signature, + }; + } else { + throw new Error("Invalid wallet client provided does not support signTypedData"); + } +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts new file mode 100644 index 0000000000..e23d73fc13 --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts @@ -0,0 +1,54 @@ +import { safeBase64Encode, safeBase64Decode } from "../../../../shared"; +import { + ExactPaymentPayload, + ExactPaymentPayloadSchema, +} from "../../../../types/verify/schemes/exact"; + +/** + * 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: ExactPaymentPayload): string { + const safe = { + ...payment, + payload: { + ...payment.payload, + authorization: Object.fromEntries( + Object.entries(payment.payload.authorization).map(([key, value]) => [ + key, + typeof value === "bigint" ? (value as bigint).toString() : value, + ]), + ), + }, + }; + 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): ExactPaymentPayload { + const decoded = safeBase64Decode(payment); + const parsed = JSON.parse(decoded); + + const obj = { + ...parsed, + payload: { + signature: parsed.payload.signature, + authorization: { + ...parsed.payload.authorization, + value: parsed.payload.authorization.value, + validAfter: parsed.payload.authorization.validAfter, + validBefore: parsed.payload.authorization.validBefore, + }, + }, + }; + + const validated = ExactPaymentPayloadSchema.parse(obj); + return validated; +} diff --git a/typescript/packages/x402/src/schemes/deferred/index.ts b/typescript/packages/x402/src/schemes/deferred/index.ts new file mode 100644 index 0000000000..f1753e0f1d --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/index.ts @@ -0,0 +1,3 @@ +export * as evm from "./evm"; + +export const SCHEME = "deferred"; diff --git a/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts b/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts index 88798dcf41..f455dd5d2d 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts @@ -3,7 +3,8 @@ import { getNetworkId } from "../../../shared"; import { getVersion, getERC20Balance } from "../../../shared/evm"; import { usdcABI as abi, - authorizationTypes, + typedDataTypes, + transferWithAuthorizationPrimaryType, config, ConnectedClient, SignerWallet, @@ -84,8 +85,8 @@ export async function verify< } // Verify permit signature is recoverable for the owner address const permitTypedData = { - types: authorizationTypes, - primaryType: "TransferWithAuthorization" as const, + types: typedDataTypes, + primaryType: transferWithAuthorizationPrimaryType, domain: { name, version, diff --git a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts new file mode 100644 index 0000000000..2d9724bf48 --- /dev/null +++ b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts @@ -0,0 +1,21 @@ +export const deferredEscrowABI = [ + { + inputs: [ + { + internalType: "bytes32", + name: "id", + type: "bytes32", + }, + ], + name: "isCollected", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, +] as const; diff --git a/typescript/packages/x402/src/types/shared/evm/eip3009.ts b/typescript/packages/x402/src/types/shared/evm/eip3009.ts deleted file mode 100644 index 25deca66ca..0000000000 --- a/typescript/packages/x402/src/types/shared/evm/eip3009.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const authorizationTypes = { - 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" }, - ], -}; - -export const authorizationPrimaryType = "TransferWithAuthorization"; diff --git a/typescript/packages/x402/src/types/shared/evm/typedData.ts b/typescript/packages/x402/src/types/shared/evm/typedData.ts new file mode 100644 index 0000000000..1686dcb82e --- /dev/null +++ b/typescript/packages/x402/src/types/shared/evm/typedData.ts @@ -0,0 +1,24 @@ +export const typedDataTypes = { + 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" }, + ], + DeferredVoucher: [ + { name: "id", type: "bytes32" }, + { name: "buyer", type: "address" }, + { name: "seller", type: "address" }, + { name: "value", type: "uint256" }, + { name: "asset", type: "address" }, + { name: "timestamp", type: "uint256" }, + { name: "nonce", type: "uint256" }, + { name: "escrow", type: "address" }, + { name: "chainId", type: "uint256" }, + ], +}; + +export const transferWithAuthorizationPrimaryType = "TransferWithAuthorization"; +export const deferredVoucherPrimaryType = "DeferredVoucher"; diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts new file mode 100644 index 0000000000..86ced7da97 --- /dev/null +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -0,0 +1,59 @@ +import { z } from "zod"; +import { + EvmAddressRegex, + EvmSignatureRegex, + HexEncoded64ByteRegex, + EvmMaxAtomicUnits, +} from "../constants"; +import { hasMaxLength, isInteger } from "../refiners"; +import { NetworkSchema, x402Versions } from "../.."; + +export const DeferredErrorReasons = [ + "invalid_deferred_evm_payload_network_mismatch", + "invalid_deferred_evm_payload_chain_id", + "invalid_deferred_evm_payload_voucher_value", + "invalid_deferred_evm_payload_recipient_mismatch", + "invalid_deferred_evm_payload_asset_mismatch", + "invalid_deferred_evm_payload_voucher_already_claimed", + "invalid_deferred_evm_payload_signature", +] as const; + +// x402DeferredEvmPayloadVoucher +export const DeferredEvmPayloadVoucherSchema = z.object({ + id: z.string().regex(HexEncoded64ByteRegex), + buyer: z.string().regex(EvmAddressRegex), + seller: z.string().regex(EvmAddressRegex), + value: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + asset: z.string().regex(EvmAddressRegex), + timestamp: z.number().int().nonnegative(), + nonce: z.number().int().nonnegative(), + escrow: z.string().regex(EvmAddressRegex), + chainId: z.number().int().nonnegative(), +}); +export type DeferredEvmPayloadVoucher = z.infer; + +// x402DeferredEvmPayload +export const DeferredEvmPayloadSchema = z.object({ + signature: z.string().regex(EvmSignatureRegex), + voucher: DeferredEvmPayloadVoucherSchema, +}); +export type DeferredEvmPayload = z.infer; + +// x402DeferredEvmPaymentPayload +export const DeferredPaymentPayloadSchema = z.object({ + x402Version: z.number().refine(val => x402Versions.includes(val as 1)), + scheme: z.literal("deferred"), + network: NetworkSchema, + payload: DeferredEvmPayloadSchema, +}); +export type DeferredPaymentPayload = z.infer; + +// x402UnsignedDeferredPaymentPayload +export const UnsignedDeferredPaymentPayloadSchema = z.object({ + x402Version: z.number().refine(val => x402Versions.includes(val as 1)), + scheme: z.literal("deferred"), + network: NetworkSchema, + payload: DeferredEvmPayloadSchema.omit({ signature: true }).extend({ + signature: z.undefined(), + }), +}); diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index 4642f91ef1..1c086320b4 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -8,6 +8,11 @@ import { ExactPaymentPayloadSchema, UnsignedExactPaymentPayloadSchema, } from "./schemes/exact"; +import { + DeferredErrorReasons, + DeferredPaymentPayloadSchema, + UnsignedDeferredPaymentPayloadSchema, +} from "./schemes/deferred"; // Enums export const schemes = ["exact", "deferred"] as const; @@ -28,6 +33,7 @@ export const ErrorReasons = [ "unexpected_settle_error", "unexpected_verify_error", ...ExactErrorReasons, + ...DeferredErrorReasons, ] as const; // x402PaymentRequirements @@ -52,10 +58,14 @@ export const PaymentRequirementsSchema = z.object({ export type PaymentRequirements = z.infer; // x402PaymentPayload -export const PaymentPayloadSchema = z.discriminatedUnion("scheme", [ExactPaymentPayloadSchema]); +export const PaymentPayloadSchema = z.discriminatedUnion("scheme", [ + ExactPaymentPayloadSchema, + DeferredPaymentPayloadSchema, +]); export type PaymentPayload = z.infer; export const UnsignedPaymentPayloadSchema = z.discriminatedUnion("scheme", [ UnsignedExactPaymentPayloadSchema, + UnsignedDeferredPaymentPayloadSchema, ]); export type UnsignedPaymentPayload = z.infer; From 39f2eca0c6bf00b04d53a2e7ccf85edaa595fbba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 16 Jul 2025 16:46:02 -0300 Subject: [PATCH 003/116] feat: implement x402 deferred scheme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/client/createPaymentHeader.ts | 10 + .../x402/src/client/preparePaymentHeader.ts | 36 +- .../x402/src/client/signPaymentHeader.ts | 16 +- .../x402/src/facilitator/facilitator.ts | 22 +- .../src/schemes/deferred/evm/client.test.ts | 401 +++++++++++------- .../x402/src/schemes/deferred/evm/client.ts | 127 ++++-- .../src/schemes/deferred/evm/facilitator.ts | 82 ++-- .../src/schemes/deferred/evm/sign.test.ts | 57 +++ .../x402/src/schemes/deferred/evm/sign.ts | 89 ++-- .../deferred/evm/utils/paymentUtils.ts | 23 +- .../x402/src/schemes/exact/evm/sign.ts | 9 +- .../src/types/shared/evm/deferredEscrowABI.ts | 12 + .../x402/src/types/shared/evm/index.ts | 2 +- .../x402/src/types/shared/evm/typedData.ts | 4 +- .../packages/x402/src/types/verify/index.ts | 3 + .../x402/src/types/verify/schemes/deferred.ts | 44 +- .../x402/src/types/verify/schemes/exact.ts | 5 +- .../x402/src/types/verify/versions.ts | 1 + .../x402/src/types/verify/x402Specs.ts | 2 +- 19 files changed, 649 insertions(+), 296 deletions(-) create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts create mode 100644 typescript/packages/x402/src/types/verify/versions.ts diff --git a/typescript/packages/x402/src/client/createPaymentHeader.ts b/typescript/packages/x402/src/client/createPaymentHeader.ts index 2aa8a5d5ee..2eebbabc23 100644 --- a/typescript/packages/x402/src/client/createPaymentHeader.ts +++ b/typescript/packages/x402/src/client/createPaymentHeader.ts @@ -1,6 +1,7 @@ import { createPaymentHeader as createPaymentHeaderExactEVM } from "../schemes/exact/evm/client"; import { createPaymentHeader as createPaymentHeaderExactSVM } from "../schemes/exact/svm/client"; import { isEvmSignerWallet, isMultiNetworkSigner, isSvmSignerWallet, MultiNetworkSigner, Signer, SupportedEVMNetworks, SupportedSVMNetworks } from "../types/shared"; +import { createPaymentHeader as createPaymentHeaderDeferredEVM } from "../schemes/deferred/evm/client"; import { PaymentRequirements } from "../types/verify"; /** @@ -47,5 +48,14 @@ export async function createPaymentHeader( } throw new Error("Unsupported network"); } + + // deferred scheme + if ( + paymentRequirements.scheme === "deferred" && + SupportedEVMNetworks.includes(paymentRequirements.network) + ) { + return await createPaymentHeaderDeferredEVM(client, x402Version, paymentRequirements); + } + throw new Error("Unsupported scheme"); } \ No newline at end of file diff --git a/typescript/packages/x402/src/client/preparePaymentHeader.ts b/typescript/packages/x402/src/client/preparePaymentHeader.ts index 986c63c95c..c168384ed9 100644 --- a/typescript/packages/x402/src/client/preparePaymentHeader.ts +++ b/typescript/packages/x402/src/client/preparePaymentHeader.ts @@ -1,11 +1,13 @@ import { Address } from "viem"; import { preparePaymentHeader as preparePaymentHeaderExactEVM } from "../schemes/exact/evm/client"; +import { preparePaymentHeader as preparePaymentHeaderDeferredEVM } from "../schemes/deferred/evm/client"; import { SupportedEVMNetworks } from "../types/shared"; import { PaymentRequirements, UnsignedPaymentPayload } from "../types/verify"; /** * Prepares a payment header with the given sender address and payment requirements. - * + * Only supports exact scheme. For deferred scheme, use preparePaymentHeaderAsync. + * * @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 @@ -25,3 +27,35 @@ export function preparePaymentHeader( throw new Error("Unsupported scheme"); } + +/** + * Prepares a payment header with the given sender address and payment requirements. + * Async version of preparePaymentHeader that supports exact and deferred schemes. + * + * @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 that can be used to create a payment header + */ +export function preparePaymentHeaderAsync( + from: Address, + x402Version: number, + paymentRequirements: PaymentRequirements, +): Promise { + + if ( + paymentRequirements.scheme === "exact" && + SupportedEVMNetworks.includes(paymentRequirements.network) + ) { + return Promise.resolve(preparePaymentHeaderExactEVM(from, x402Version, paymentRequirements)); + } + + if ( + paymentRequirements.scheme === "deferred" && + SupportedEVMNetworks.includes(paymentRequirements.network) + ) { + return preparePaymentHeaderDeferredEVM(from, x402Version, paymentRequirements); + } + + throw new Error("Unsupported scheme"); +} \ No newline at end of file diff --git a/typescript/packages/x402/src/client/signPaymentHeader.ts b/typescript/packages/x402/src/client/signPaymentHeader.ts index 9dd0126831..783f590723 100644 --- a/typescript/packages/x402/src/client/signPaymentHeader.ts +++ b/typescript/packages/x402/src/client/signPaymentHeader.ts @@ -1,7 +1,10 @@ import { signPaymentHeader as signPaymentHeaderExactEVM } from "../schemes/exact/evm/client"; -import { encodePayment } from "../schemes/exact/evm/utils/paymentUtils"; import { isEvmSignerWallet, isMultiNetworkSigner, MultiNetworkSigner, Signer, SupportedEVMNetworks } from "../types/shared"; +import { signPaymentHeader as signPaymentHeaderDeferredEVM } from "../schemes/deferred/evm/client"; +import { encodePayment as encodePaymentExactEVM } from "../schemes/exact/evm/utils/paymentUtils"; +import { encodePayment as encodePaymentDeferredEVM } from "../schemes/deferred/evm/utils/paymentUtils"; import { PaymentRequirements, UnsignedPaymentPayload } from "../types/verify"; +import { UnsignedDeferredPaymentPayloadSchema } from "../types/verify/schemes/deferred"; import { UnsignedExactPaymentPayloadSchema } from "../types/verify/schemes/exact"; /** @@ -28,7 +31,16 @@ export async function signPaymentHeader( } unsignedPaymentHeader = UnsignedExactPaymentPayloadSchema.parse(unsignedPaymentHeader); const signedPaymentHeader = await signPaymentHeaderExactEVM(client, paymentRequirements, unsignedPaymentHeader); - return encodePayment(signedPaymentHeader); + return encodePaymentExactEVM(signedPaymentHeader); + } + + if ( + paymentRequirements.scheme === "deferred" && + SupportedEVMNetworks.includes(paymentRequirements.network) + ) { + unsignedPaymentHeader = UnsignedDeferredPaymentPayloadSchema.parse(unsignedPaymentHeader); + const signedPaymentHeader = await signPaymentHeaderDeferredEVM(client, unsignedPaymentHeader); + return encodePaymentDeferredEVM(signedPaymentHeader); } throw new Error("Unsupported scheme"); diff --git a/typescript/packages/x402/src/facilitator/facilitator.ts b/typescript/packages/x402/src/facilitator/facilitator.ts index 0fc6164b2d..c61e6ad06b 100644 --- a/typescript/packages/x402/src/facilitator/facilitator.ts +++ b/typescript/packages/x402/src/facilitator/facilitator.ts @@ -1,5 +1,6 @@ import { verify as verifyExactEvm, settle as settleExactEvm } from "../schemes/exact/evm"; import { verify as verifyExactSvm, settle as settleExactSvm } from "../schemes/exact/svm"; +import { verify as verifyDeferred, settle as settleDeferred } from "../schemes/deferred/evm"; import { SupportedEVMNetworks, SupportedSVMNetworks } from "../types/shared"; import { ConnectedClient as EvmConnectedClient, @@ -54,9 +55,7 @@ export async function verify< } } -<<<<<<< HEAD - // unsupported scheme -======= + // deferred scheme if (paymentRequirements.scheme == "deferred") { payload = DeferredPaymentPayloadSchema.parse(payload); if (SupportedEVMNetworks.includes(paymentRequirements.network)) { @@ -71,7 +70,7 @@ export async function verify< } } ->>>>>>> 69d9ed0 (wip: implement deferred scheme) + // unsupported scheme return { isValid: false, invalidReason: "invalid_scheme", @@ -113,6 +112,21 @@ export async function settle( } } + if (paymentRequirements.scheme == "deferred") { + payload = DeferredPaymentPayloadSchema.parse(payload); + if (SupportedEVMNetworks.includes(paymentRequirements.network)) { + return settleDeferred(client, payload, paymentRequirements); + } else { + return { + success: false, + errorReason: "invalid_scheme", + transaction: "", + network: paymentRequirements.network, + payer: payload.payload.voucher.buyer, + }; + } + } + return { success: false, errorReason: "invalid_scheme", diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts index 02527309fd..2ad85fa1a7 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -1,37 +1,48 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { createSignerSepolia, SignerWallet } from "../../../types/shared/evm"; -import { PaymentRequirements, UnsignedPaymentPayload } from "../../../types/verify"; +import { createSigner } from "../../../types/shared/evm"; +import { PaymentRequirements } from "../../../types/verify"; import { createPaymentHeader, preparePaymentHeader, signPaymentHeader } from "./client"; -import { signAuthorization } from "./sign"; +import { + DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, + DeferredEvmPaymentRequirementsSchema, + UnsignedDeferredPaymentPayload, +} from "../../../types/verify/schemes/deferred"; import { encodePayment } from "./utils/paymentUtils"; -vi.mock("./sign", async () => { - const actual = await vi.importActual("./sign"); - return { - ...actual, - signAuthorization: vi.fn(), - }; -}); - vi.mock("./utils/paymentUtils", () => ({ encodePayment: vi.fn().mockReturnValue("encoded-payment-header"), })); -describe("preparePaymentHeader", () => { +const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", +); +const buyerAddress = buyer.account.address; +const sellerAddress = "0x1234567890123456789012345678901234567890"; +const escrowAddress = "0xffffff12345678901234567890123456789fffff"; +const assetAddress = "0x1111111111111111111111111111111111111111"; +const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; + +describe("preparePaymentHeader: new voucher", () => { const mockPaymentRequirements: PaymentRequirements = { - scheme: "exact", + scheme: "deferred", network: "base-sepolia", maxAmountRequired: "1000000", resource: "https://example.com/resource", description: "Test resource", mimeType: "application/json", - payTo: "0x1234567890123456789012345678901234567890", + payTo: sellerAddress, maxTimeoutSeconds: 300, - asset: "0x1234567890123456789012345678901234567890", + asset: assetAddress, + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + }, }; - const mockFromAddress = "0xabcdef1234567890123456789012345678901234"; - beforeEach(() => { vi.useFakeTimers(); // Set a fixed time for consistent testing @@ -43,204 +54,308 @@ describe("preparePaymentHeader", () => { vi.useRealTimers(); }); - it("should create a valid unsigned payment header", () => { - const result = preparePaymentHeader(mockFromAddress, 1, mockPaymentRequirements); - const currentTime = Math.floor(Date.now() / 1000); + it("should create a valid unsigned payment header", async () => { + const paymentHeader = await preparePaymentHeader(buyerAddress, 1, mockPaymentRequirements); - expect(result).toEqual({ + const parsedPaymentRequirements = + DeferredEvmPaymentRequirementsSchema.parse(mockPaymentRequirements); + + expect(paymentHeader).toEqual({ x402Version: 1, - scheme: "exact", + scheme: "deferred", network: "base-sepolia", payload: { signature: undefined, - authorization: { - from: mockFromAddress, - to: mockPaymentRequirements.payTo, - value: mockPaymentRequirements.maxAmountRequired, - validAfter: (currentTime - 600).toString(), - validBefore: (currentTime + mockPaymentRequirements.maxTimeoutSeconds).toString(), - nonce: expect.any(String), + voucher: { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + value: parsedPaymentRequirements.maxAmountRequired, + asset: assetAddress, + timestamp: expect.any(Number), + nonce: 0, + escrow: escrowAddress, + chainId: 84532, }, }, }); }); - it("should generate a unique nonce for each call", () => { - const result1 = preparePaymentHeader(mockFromAddress, 1, mockPaymentRequirements); - const result2 = preparePaymentHeader(mockFromAddress, 1, mockPaymentRequirements); - - expect(result1.payload.authorization.nonce.length).toBe(66); - expect(result2.payload.authorization.nonce.length).toBe(66); - expect(result1.payload.authorization.nonce).not.toBe(result2.payload.authorization.nonce); + it("should revert if paymentRequirement.extra required fields are missing", async () => { + const requiredFields = ["id", "escrow"]; + for (const field of requiredFields) { + const badPaymentRequirements = structuredClone(mockPaymentRequirements); + delete badPaymentRequirements.extra!.voucher[field]; + await expect(preparePaymentHeader(buyerAddress, 1, badPaymentRequirements)).rejects.toThrow(); + } }); - it("should calculate validAfter as 60 seconds before current time", () => { - const result = preparePaymentHeader(mockFromAddress, 1, mockPaymentRequirements); - const currentTime = Math.floor(Date.now() / 1000); - const validAfter = parseInt(result.payload.authorization.validAfter); - - expect(validAfter).toBe(currentTime - 600); + it("should revert if paymentRequirement.extra required fields have invalid values", async () => { + const requiredFields = ["id", "escrow"]; + for (const field of requiredFields) { + const badPaymentRequirements = structuredClone(mockPaymentRequirements); + badPaymentRequirements.extra!.voucher[field] = "0x"; + await expect(preparePaymentHeader(buyerAddress, 1, badPaymentRequirements)).rejects.toThrow(); + } }); - it("should calculate validBefore as current time plus maxTimeoutSeconds", () => { - const result = preparePaymentHeader(mockFromAddress, 1, mockPaymentRequirements); - const currentTime = Math.floor(Date.now() / 1000); - const validBefore = parseInt(result.payload.authorization.validBefore); - - expect(validBefore).toBe(currentTime + mockPaymentRequirements.maxTimeoutSeconds); - }); - - it("should handle different x402 versions", () => { - const result = preparePaymentHeader(mockFromAddress, 2, mockPaymentRequirements); + it("should handle different x402 versions", async () => { + const result = await preparePaymentHeader(buyerAddress, 2, mockPaymentRequirements); expect(result.x402Version).toBe(2); }); }); -describe("signPaymentHeader", () => { - const mockPaymentRequirements: PaymentRequirements = { - scheme: "exact", +describe("preparePaymentHeader: aggregated voucher", () => { + const mockAggregatedPaymentRequirements: PaymentRequirements = { + scheme: "deferred", network: "base-sepolia", maxAmountRequired: "1000000", resource: "https://example.com/resource", description: "Test resource", mimeType: "application/json", - payTo: "0x1234567890123456789012345678901234567890", + payTo: sellerAddress, maxTimeoutSeconds: 300, - asset: "0x1234567890123456789012345678901234567890", - }; - - const mockUnsignedHeader: UnsignedPaymentPayload = { - x402Version: 1, - scheme: "exact", - network: "base-sepolia", - payload: { - signature: undefined, - authorization: { - from: "0xabcdef1234567890123456789012345678901234", - to: "0x1234567890123456789012345678901234567890", + asset: assetAddress, + extra: { + type: "aggregation", + signature: + "0xca991563e3929ae2027b7c8bda0fc580ad1c2390f7831ae814a2b5ec5c31e22d7e5efced8d66dd7eccb5fba63e85ffa6ae1583b0c5e85c2baf1a3aaf639e465f1c", + voucher: { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, value: "1000000", - validAfter: "1704067195", - validBefore: "1704067495", - nonce: "1234567890", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, }, }, }; - const mockSignature = "0x1234567890123456789012345678901234567890123456789012345678901234"; + beforeEach(() => { + vi.useFakeTimers(); + // Set a fixed time for consistent testing + vi.setSystemTime(new Date("2024-01-01T00:00:00Z")); + vi.clearAllMocks(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); - const createTestClient = () => { - return createSignerSepolia( - "0x1234567890123456789012345678901234567890123456789012345678901234", + it("should create a valid unsigned payment header", async () => { + const paymentHeader = await preparePaymentHeader( + buyerAddress, + 1, + mockAggregatedPaymentRequirements, ); - }; - beforeEach(() => { - vi.clearAllMocks(); - vi.mocked(signAuthorization).mockResolvedValue({ signature: mockSignature }); + const parsedExtra = DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema.parse( + mockAggregatedPaymentRequirements.extra, + ); + + expect(paymentHeader).toEqual({ + x402Version: 1, + scheme: "deferred", + network: "base-sepolia", + payload: { + signature: undefined, + voucher: { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + value: ( + BigInt(mockAggregatedPaymentRequirements.maxAmountRequired) + + BigInt(parsedExtra.voucher.value) + ).toString(), + asset: assetAddress, + timestamp: expect.any(Number), + nonce: 1, + escrow: escrowAddress, + chainId: 84532, + }, + }, + }); }); - it("should sign the payment header and return a complete payload", async () => { - const client = createTestClient(); - const result = await signPaymentHeader(client, mockPaymentRequirements, mockUnsignedHeader); + it("should revert if voucher signature is invalid", async () => { + // Inject incorrect signature into mockAggregatedPaymentRequirements + const paymentRequirements = structuredClone(mockAggregatedPaymentRequirements); + paymentRequirements.extra!.signature = + "0x79ce97f6d1242aa7b6f4826efb553ed453fd6c7132c665d95bc226d5f3027dd5456d61ed1bd8da5de6cea4d8154070ff458300b6b84e0c9010f434af77ad3d291c"; - expect(signAuthorization).toHaveBeenCalledWith( - client, - mockUnsignedHeader.payload.authorization, - mockPaymentRequirements, + await expect(preparePaymentHeader(buyerAddress, 1, paymentRequirements)).rejects.toThrow( + "Invalid voucher signature", ); + }); + + it("should revert if paymentRequirement.extra required fields are missing", async () => { + const requiredFields = [ + "id", + "buyer", + "seller", + "value", + "asset", + "timestamp", + "nonce", + "escrow", + "chainId", + ]; + for (const field of requiredFields) { + const badPaymentRequirements = structuredClone(mockAggregatedPaymentRequirements); + delete badPaymentRequirements.extra!.voucher[field]; + await expect(preparePaymentHeader(buyerAddress, 1, badPaymentRequirements)).rejects.toThrow(); + } + }); + + it("should revert if paymentRequirement.extra required fields have invalid values", async () => { + const requiredFields = [ + "id", + "buyer", + "seller", + "value", + "asset", + "timestamp", + "nonce", + "escrow", + "chainId", + ]; + for (const field of requiredFields) { + const badPaymentRequirements = structuredClone(mockAggregatedPaymentRequirements); + badPaymentRequirements.extra!.voucher[field] = "0x"; + await expect(preparePaymentHeader(buyerAddress, 1, badPaymentRequirements)).rejects.toThrow(); + } + }); + + it("should handle different x402 versions", async () => { + const result = await preparePaymentHeader(buyerAddress, 2, mockAggregatedPaymentRequirements); + expect(result.x402Version).toBe(2); + }); +}); + +describe("signPaymentHeader", () => { + const mockUnsignedHeader: UnsignedDeferredPaymentPayload = { + x402Version: 1, + scheme: "deferred", + network: "base-sepolia", + payload: { + signature: undefined, + voucher: { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + value: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + }, + }, + }; + const mockVoucherSignature = + "0xca991563e3929ae2027b7c8bda0fc580ad1c2390f7831ae814a2b5ec5c31e22d7e5efced8d66dd7eccb5fba63e85ffa6ae1583b0c5e85c2baf1a3aaf639e465f1c"; + + it("should sign the payment header and return a complete payload", async () => { + const signedPaymentPayload = await signPaymentHeader(buyer, mockUnsignedHeader); - expect(result).toEqual({ + expect(signedPaymentPayload).toEqual({ ...mockUnsignedHeader, payload: { ...mockUnsignedHeader.payload, - signature: mockSignature, + signature: mockVoucherSignature, }, }); }); it("should preserve all original fields in the signed payload", async () => { - const client = createTestClient(); - const result = await signPaymentHeader(client, mockPaymentRequirements, mockUnsignedHeader); + const signedPaymentPayload = await signPaymentHeader(buyer, mockUnsignedHeader); // Check that all original fields are preserved - expect(result.x402Version).toBe(mockUnsignedHeader.x402Version); - expect(result.scheme).toBe(mockUnsignedHeader.scheme); - expect(result.network).toBe(mockUnsignedHeader.network); - expect(result.payload.authorization).toEqual(mockUnsignedHeader.payload.authorization); + expect(signedPaymentPayload.x402Version).toBe(mockUnsignedHeader.x402Version); + expect(signedPaymentPayload.scheme).toBe(mockUnsignedHeader.scheme); + expect(signedPaymentPayload.network).toBe(mockUnsignedHeader.network); + expect(signedPaymentPayload.payload.voucher).toEqual(mockUnsignedHeader.payload.voucher); }); it("should throw an error if signing fails", async () => { - const client = createTestClient(); - const error = new Error("Signing failed"); - vi.mocked(signAuthorization).mockRejectedValue(error); - - await expect( - signPaymentHeader(client, mockPaymentRequirements, mockUnsignedHeader), - ).rejects.toThrow("Signing failed"); + const badUnsignedHeader = {} as UnsignedDeferredPaymentPayload; + await expect(signPaymentHeader(buyer, badUnsignedHeader)).rejects.toThrow(); }); }); describe("createPaymentHeader", () => { const mockPaymentRequirements: PaymentRequirements = { - scheme: "exact", + scheme: "deferred", network: "base-sepolia", maxAmountRequired: "1000000", resource: "https://example.com/resource", description: "Test resource", mimeType: "application/json", - payTo: "0x1234567890123456789012345678901234567890", + payTo: sellerAddress, maxTimeoutSeconds: 300, - asset: "0x1234567890123456789012345678901234567890", + asset: assetAddress, + extra: { + type: "aggregation", + signature: + "0xca991563e3929ae2027b7c8bda0fc580ad1c2390f7831ae814a2b5ec5c31e22d7e5efced8d66dd7eccb5fba63e85ffa6ae1583b0c5e85c2baf1a3aaf639e465f1c", + voucher: { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + value: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + }, + }, }; const mockSignedPayment = { x402Version: 1, - scheme: "exact", + scheme: "deferred", network: "base-sepolia", payload: { signature: - "0x1234567890123456789012345678901234567890123456789012345678901234" as `0x${string}`, - authorization: { - from: "0xabcdef1234567890123456789012345678901234" as `0x${string}`, - to: "0x1234567890123456789012345678901234567890" as `0x${string}`, - value: "1000000", - validAfter: "1704067195", - validBefore: "1704067495", - nonce: "1234567890", + "0x583c4822217a0a8d9f079800a4abf48ea4f366438181cf24a53a95567e1430442d3c8974edbd0b9d3d9c0d1231c6bbf837848986a7157f7f6056e2f6d4d7433a1b", + voucher: { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + value: "2000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 1, + escrow: escrowAddress, + chainId: 84532, }, }, }; - const createTestClient = () => { - const client = createSignerSepolia( - "0x1234567890123456789012345678901234567890123456789012345678901234" as `0x${string}`, - ); - return client as unknown as SignerWallet; - }; - - beforeEach(() => { - vi.clearAllMocks(); - vi.mocked(signAuthorization).mockResolvedValue({ - signature: mockSignedPayment.payload.signature, - }); - }); - it("should create and encode a payment header", async () => { - const client = createTestClient(); - const result = await createPaymentHeader(client, 1, mockPaymentRequirements); - + const result = await createPaymentHeader(buyer, 1, mockPaymentRequirements); expect(result).toBe("encoded-payment-header"); expect(vi.mocked(encodePayment)).toHaveBeenCalledWith( expect.objectContaining({ x402Version: 1, - scheme: "exact", + scheme: "deferred", network: "base-sepolia", payload: expect.objectContaining({ - signature: mockSignedPayment.payload.signature, - authorization: expect.objectContaining({ - from: client.account!.address, - to: mockPaymentRequirements.payTo, - value: mockPaymentRequirements.maxAmountRequired, + signature: expect.any(String), + voucher: expect.objectContaining({ + id: mockSignedPayment.payload.voucher.id, + buyer: mockSignedPayment.payload.voucher.buyer, + seller: mockSignedPayment.payload.voucher.seller, + value: mockSignedPayment.payload.voucher.value, + asset: mockSignedPayment.payload.voucher.asset, + timestamp: expect.any(Number), + nonce: mockSignedPayment.payload.voucher.nonce, + escrow: mockSignedPayment.payload.voucher.escrow, + chainId: mockSignedPayment.payload.voucher.chainId, }), }), }), @@ -248,8 +363,7 @@ describe("createPaymentHeader", () => { }); it("should handle different x402 versions", async () => { - const client = createTestClient(); - await createPaymentHeader(client, 2, mockPaymentRequirements); + await createPaymentHeader(buyer, 2, mockPaymentRequirements); expect(vi.mocked(encodePayment)).toHaveBeenCalledWith( expect.objectContaining({ @@ -259,23 +373,16 @@ describe("createPaymentHeader", () => { }); it("should throw an error if signing fails", async () => { - const client = createTestClient(); - const error = new Error("Signing failed"); - vi.mocked(signAuthorization).mockRejectedValue(error); - - await expect(createPaymentHeader(client, 1, mockPaymentRequirements)).rejects.toThrow( - "Signing failed", - ); + await expect(createPaymentHeader(buyer, 1, {} as PaymentRequirements)).rejects.toThrow(); }); it("should throw an error if encoding fails", async () => { - const client = createTestClient(); const error = new Error("Encoding failed"); vi.mocked(encodePayment).mockImplementation(() => { throw error; }); - await expect(createPaymentHeader(client, 1, mockPaymentRequirements)).rejects.toThrow( + await expect(createPaymentHeader(buyer, 1, mockPaymentRequirements)).rejects.toThrow( "Encoding failed", ); }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index d5dbd9825e..c1709bb442 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -1,12 +1,18 @@ -import { Address, Chain, LocalAccount, Transport } from "viem"; +import { Address, Chain, Hex, LocalAccount, Transport } from "viem"; import { isSignerWallet, SignerWallet } from "../../../types/shared/evm"; import { PaymentRequirements } from "../../../types/verify"; -import { createNonce, signAuthorization } from "./sign"; +import { signVoucher, verifyVoucher } from "./sign"; import { encodePayment } from "./utils/paymentUtils"; import { - ExactPaymentPayload, - UnsignedExactPaymentPayload, -} from "../../../types/verify/schemes/exact"; + DeferredEvmPayloadVoucher, + DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, + DeferredEvmPaymentRequirementsExtraNewVoucherSchema, + DeferredEvmPaymentRequirements, + DeferredEvmPaymentRequirementsSchema, + DeferredPaymentPayload, + UnsignedDeferredPaymentPayload, +} from "../../../types/verify/schemes/deferred"; +import { getNetworkId } from "../../../shared/network"; /** * Prepares an unsigned payment header with the given sender address and payment requirements. @@ -16,56 +22,107 @@ import { * @param paymentRequirements - The payment requirements containing scheme and network information * @returns An unsigned payment payload containing authorization details */ -export function preparePaymentHeader( +export async function preparePaymentHeader( from: Address, x402Version: number, paymentRequirements: PaymentRequirements, -): UnsignedExactPaymentPayload { - const nonce = createNonce(); +): Promise { + const deferredPaymentRequirements = + DeferredEvmPaymentRequirementsSchema.parse(paymentRequirements); - const validAfter = BigInt( - Math.floor(Date.now() / 1000) - 600, // 10 minutes before - ).toString(); - const validBefore = BigInt( - Math.floor(Date.now() / 1000 + paymentRequirements.maxTimeoutSeconds), - ).toString(); + const voucher = + deferredPaymentRequirements.extra.type === "new" + ? createNewVoucher(from, deferredPaymentRequirements) + : await aggregateVoucher(from, deferredPaymentRequirements); return { x402Version, - scheme: "exact", + scheme: "deferred", network: paymentRequirements.network, payload: { signature: undefined, - authorization: { - from, - to: paymentRequirements.payTo as Address, - value: paymentRequirements.maxAmountRequired, - validAfter: validAfter.toString(), - validBefore: validBefore.toString(), - nonce, - }, + voucher: voucher, }, }; } +/** + * Creates a new voucher with the given payment requirements + * + * @param from - The sender's address from which the payment will be made + * @param paymentRequirements - The payment requirements containing scheme and network information + * @returns The new voucher + */ +export function createNewVoucher( + from: Address, + paymentRequirements: DeferredEvmPaymentRequirements, +): DeferredEvmPayloadVoucher { + const extra = DeferredEvmPaymentRequirementsExtraNewVoucherSchema.parse( + paymentRequirements.extra, + ); + + return { + id: extra.voucher.id, + buyer: from, + seller: paymentRequirements.payTo, + value: paymentRequirements.maxAmountRequired, + asset: paymentRequirements.asset, + timestamp: Math.floor(Date.now() / 1000), + nonce: 0, + escrow: extra.voucher.escrow, + chainId: getNetworkId(paymentRequirements.network), + }; +} + +/** + * Aggregates a voucher with new payment requirements + * + * @param from - The sender's address from which the payment will be made + * @param paymentRequirements - The payment requirements containing scheme and network information + * @returns The aggregated voucher + */ +export async function aggregateVoucher( + from: Address, + paymentRequirements: DeferredEvmPaymentRequirements, +): Promise { + const extra = DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema.parse( + paymentRequirements.extra, + ); + + // verify signature is valid and the voucher's buyer is the client + const isValid = await verifyVoucher(extra.voucher, extra.signature as Hex, from); + if (!isValid) { + throw new Error("Invalid voucher signature"); + } + + const { id, escrow, buyer, seller, value, asset, nonce, chainId } = extra.voucher; + const newTimestamp = Math.floor(Date.now() / 1000); + + return { + id, + buyer, + seller, + value: (BigInt(paymentRequirements.maxAmountRequired) + BigInt(value)).toString(), + asset, + timestamp: newTimestamp, + nonce: nonce + 1, + escrow, + chainId, + }; +} + /** * 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 */ export async function signPaymentHeader( client: SignerWallet | LocalAccount, - paymentRequirements: PaymentRequirements, - unsignedPaymentHeader: UnsignedExactPaymentPayload, -): Promise { - const { signature } = await signAuthorization( - client, - unsignedPaymentHeader.payload.authorization, - paymentRequirements, - ); + unsignedPaymentHeader: UnsignedDeferredPaymentPayload, +): Promise { + const { signature } = await signVoucher(client, unsignedPaymentHeader.payload.voucher); return { ...unsignedPaymentHeader, @@ -88,10 +145,10 @@ export async function createPayment | LocalAccount, x402Version: number, paymentRequirements: PaymentRequirements, -): Promise { +): Promise { const from = isSignerWallet(client) ? client.account!.address : client.address; - const unsignedPaymentHeader = preparePaymentHeader(from, x402Version, paymentRequirements); - return signPaymentHeader(client, paymentRequirements, unsignedPaymentHeader); + const unsignedPaymentHeader = await preparePaymentHeader(from, x402Version, paymentRequirements); + return signPaymentHeader(client, unsignedPaymentHeader); } /** diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 70a4e8c14c..16a26962fe 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -1,17 +1,21 @@ -import { Account, Address, Chain, getAddress, Hex, parseErc6492Signature, Transport } from "viem"; +import { + Account, + Address, + Chain, + getAddress, + Hex, + encodeAbiParameters, + parseAbiParameters, + Transport, +} from "viem"; import { getNetworkId } from "../../../shared"; import { getERC20Balance } from "../../../shared/evm"; -import { - usdcABI as abi, - typedDataTypes, - ConnectedClient, - SignerWallet, - deferredVoucherPrimaryType, -} from "../../../types/shared/evm"; +import { ConnectedClient, SignerWallet } from "../../../types/shared/evm"; import { PaymentRequirements, SettleResponse, VerifyResponse } from "../../../types/verify"; import { SCHEME } from "../../deferred"; import { DeferredPaymentPayload } from "../../../types/verify/schemes/deferred"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; +import { verifyVoucher } from "./sign"; /** * Verifies a payment payload against the required payment details @@ -103,23 +107,12 @@ export async function verify< } // Verify voucher signature is recoverable for the owner address - const voucherTypedData = { - types: typedDataTypes, - primaryType: deferredVoucherPrimaryType, - domain: { - name: "VoucherEscrow", - version: "1", - chainId, - verifyingContract: payload.payload.voucher.escrow as Address, - }, - message: payload.payload.voucher, - }; - const recoveredAddress = await client.verifyTypedData({ - address: payload.payload.voucher.buyer as Address, - ...voucherTypedData, - signature: payload.payload.signature as Hex, - }); - if (!recoveredAddress) { + const voucherSignatureIsValid = await verifyVoucher( + payload.payload.voucher, + payload.payload.signature as Hex, + payload.payload.voucher.buyer as Address, + ); + if (!voucherSignatureIsValid) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_signature", @@ -172,9 +165,9 @@ export async function verify< } /** - * Settles a payment by executing a USDC transferWithAuthorization transaction + * Settles a payment by executing a collect transaction on the deferred escrow contract * - * This function executes the actual USDC transfer using the signed authorization from the user. + * This function executes the collect transaction using a signed voucher. * The facilitator wallet submits the transaction but does not need to hold or transfer any tokens itself. * * @param wallet - The facilitator wallet that will submit the transaction @@ -184,7 +177,7 @@ export async function verify< */ export async function settle( wallet: SignerWallet, - paymentPayload: ExactPaymentPayload, + paymentPayload: DeferredPaymentPayload, paymentRequirements: PaymentRequirements, ): Promise { // re-verify to ensure the payment is still valid @@ -195,27 +188,22 @@ export async function settle( success: false, network: paymentPayload.network, transaction: "", - errorReason: valid.invalidReason ?? "invalid_scheme", //`Payment is no longer valid: ${valid.invalidReason}`, - payer: paymentPayload.payload.authorization.from, + errorReason: valid.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", + payer: paymentPayload.payload.voucher.buyer, }; } - // Returns the original signature (no-op) if the signature is not a 6492 signature - const { signature } = parseErc6492Signature(paymentPayload.payload.signature as Hex); + const { voucher, signature } = paymentPayload.payload; + const abiTypes = parseAbiParameters( + "(tuple(bytes32 id, address buyer, address seller, uint256 value, address asset, uint256 timestamp, uint256 nonce, address escrow, uint256 chainId) voucher, bytes signature)", + ); + const encodedData = encodeAbiParameters(abiTypes, [[voucher, signature]]); const tx = await wallet.writeContract({ - address: paymentRequirements.asset as Address, - abi, - functionName: "transferWithAuthorization" as const, - args: [ - paymentPayload.payload.authorization.from as Address, - paymentPayload.payload.authorization.to as Address, - BigInt(paymentPayload.payload.authorization.value), - BigInt(paymentPayload.payload.authorization.validAfter), - BigInt(paymentPayload.payload.authorization.validBefore), - paymentPayload.payload.authorization.nonce as Hex, - signature, - ], + address: voucher.escrow as Address, + abi: deferredEscrowABI, + functionName: "collect" as const, + args: [encodedData], chain: wallet.chain as Chain, }); @@ -224,10 +212,10 @@ export async function settle( if (receipt.status !== "success") { return { success: false, - errorReason: "invalid_transaction_state", //`Transaction failed`, + errorReason: "invalid_transaction_state", transaction: tx, network: paymentPayload.network, - payer: paymentPayload.payload.authorization.from, + payer: paymentPayload.payload.voucher.buyer, }; } @@ -235,6 +223,6 @@ export async function settle( success: true, transaction: tx, network: paymentPayload.network, - payer: paymentPayload.payload.authorization.from, + payer: paymentPayload.payload.voucher.buyer, }; } diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts new file mode 100644 index 0000000000..778cd00eda --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts @@ -0,0 +1,57 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { createSigner } from "../../../types/shared/evm"; +import { signVoucher, verifyVoucher } from "./sign"; + +const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", +); +const buyerAddress = buyer.account.address; +const anotherBuyerAddress = "0x9234567890123456789012345678901234567890"; +const sellerAddress = "0x1234567890123456789012345678901234567890"; +const escrowAddress = "0xffffff12345678901234567890123456789fffff"; +const assetAddress = "0x1111111111111111111111111111111111111111"; +const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; + +describe("voucher signature", () => { + const mockVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + value: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + }; + + const mockVoucherSignature = + "0xca991563e3929ae2027b7c8bda0fc580ad1c2390f7831ae814a2b5ec5c31e22d7e5efced8d66dd7eccb5fba63e85ffa6ae1583b0c5e85c2baf1a3aaf639e465f1c"; + + beforeEach(() => { + vi.useFakeTimers(); + // Set a fixed time for consistent testing + vi.setSystemTime(new Date("2024-01-01T00:00:00Z")); + vi.clearAllMocks(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it("should create a valid voucher signature", async () => { + const signature = await signVoucher(buyer, mockVoucher); + expect(signature.signature).toBe(mockVoucherSignature); + }); + + it("should verify a valid voucher signature", async () => { + const isValid = await verifyVoucher(mockVoucher, mockVoucherSignature, buyerAddress); + expect(isValid).toBe(true); + }); + + it("should return false if voucher signature is valid but for a different buyer", async () => { + const isValid = await verifyVoucher(mockVoucher, mockVoucherSignature, anotherBuyerAddress); + expect(isValid).toBe(false); + }); +}); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts index 2d681f482e..d5b4eb07c7 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts @@ -1,56 +1,44 @@ -import { Chain, getAddress, Hex, LocalAccount, toHex, Transport } from "viem"; -import { getNetworkId } from "../../../shared"; +import { Address, Chain, getAddress, Hex, LocalAccount, Transport, verifyTypedData } from "viem"; import { - authorizationTypes, + typedDataTypes, isAccount, isSignerWallet, SignerWallet, + deferredVoucherPrimaryType, } from "../../../types/shared/evm"; -import { PaymentRequirements } from "../../../types/verify"; -import { ExactEvmPayloadAuthorization } from "../../../types/verify/schemes/exact"; +import { DeferredEvmPayloadVoucher } from "../../../types/verify/schemes/deferred"; /** - * Signs an EIP-3009 authorization for USDC transfer + * Signs a voucher * * @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 + * @param voucher - The voucher to sign * @returns The signature for the authorization */ -export async function signAuthorization( +export async function signVoucher( walletClient: SignerWallet | LocalAccount, - { from, to, value, validAfter, validBefore, nonce }: ExactEvmPayloadAuthorization, - { asset, network, extra }: PaymentRequirements, + voucher: DeferredEvmPayloadVoucher, ): Promise<{ signature: Hex }> { - const chainId = getNetworkId(network); - const name = extra?.name; - const version = extra?.version; - + const { id, buyer, seller, value, asset, timestamp, nonce, escrow, chainId } = voucher; const data = { - types: authorizationTypes, + types: typedDataTypes, + primaryType: deferredVoucherPrimaryType, domain: { - name, - version, + name: "VoucherEscrow", + version: "1", chainId, - verifyingContract: getAddress(asset), + verifyingContract: getAddress(escrow), }, - primaryType: "TransferWithAuthorization" as const, message: { - from: getAddress(from), - to: getAddress(to), + id, + buyer, + seller, value, - validAfter, - validBefore, - nonce: nonce, + asset, + timestamp, + nonce, + escrow, + chainId, }, }; @@ -68,3 +56,36 @@ export async function signAuthorization [ + voucher: Object.fromEntries( + Object.entries(payment.payload.voucher).map(([key, value]) => [ key, typeof value === "bigint" ? (value as bigint).toString() : value, ]), @@ -32,7 +32,7 @@ export function encodePayment(payment: ExactPaymentPayload): string { * @param payment - The base64 encoded payment string to decode * @returns The decoded and validated PaymentPayload object */ -export function decodePayment(payment: string): ExactPaymentPayload { +export function decodePayment(payment: string): DeferredPaymentPayload { const decoded = safeBase64Decode(payment); const parsed = JSON.parse(decoded); @@ -40,15 +40,12 @@ export function decodePayment(payment: string): ExactPaymentPayload { ...parsed, payload: { signature: parsed.payload.signature, - authorization: { - ...parsed.payload.authorization, - value: parsed.payload.authorization.value, - validAfter: parsed.payload.authorization.validAfter, - validBefore: parsed.payload.authorization.validBefore, + voucher: { + ...parsed.payload.voucher, }, }, }; - const validated = ExactPaymentPayloadSchema.parse(obj); + const validated = DeferredPaymentPayloadSchema.parse(obj); return validated; } diff --git a/typescript/packages/x402/src/schemes/exact/evm/sign.ts b/typescript/packages/x402/src/schemes/exact/evm/sign.ts index 726197b3cc..02838c3bbd 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/sign.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/sign.ts @@ -1,11 +1,6 @@ import { Chain, getAddress, Hex, LocalAccount, toHex, Transport } from "viem"; import { getNetworkId } from "../../../shared"; -import { - authorizationTypes, - isAccount, - isSignerWallet, - SignerWallet, -} from "../../../types/shared/evm"; +import { typedDataTypes, isAccount, isSignerWallet, SignerWallet } from "../../../types/shared/evm"; import { PaymentRequirements } from "../../../types/verify"; import { ExactEvmPayloadAuthorization } from "../../../types/verify/schemes/exact"; @@ -36,7 +31,7 @@ export async function signAuthorization; + +// x402DeferredEvmPaymentRequirementsExtraNewVoucher +export const DeferredEvmPaymentRequirementsExtraNewVoucherSchema = z.object({ + type: z.literal("new"), + voucher: DeferredEvmPayloadVoucherSchema.pick({ id: true, escrow: true }), +}); +export type DeferredEvmPaymentRequirementsExtraNewVoucher = z.infer< + typeof DeferredEvmPaymentRequirementsExtraNewVoucherSchema +>; + +// x402DeferredEvmPaymentRequirementsExtraAggregationVoucher +export const DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema = z.object({ + type: z.literal("aggregation"), + signature: z.string().regex(EvmSignatureRegex), + voucher: DeferredEvmPayloadVoucherSchema, +}); +export type DeferredEvmPaymentRequirementsExtraAggregationVoucher = z.infer< + typeof DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema +>; + +// x402DeferredEvmPaymentRequirements +export const DeferredEvmPaymentRequirementsSchema = z.object({ + scheme: z.literal("deferred"), + network: NetworkSchema, + maxAmountRequired: z.string().refine(isInteger), + resource: z.string().url(), + description: z.string(), + mimeType: z.string(), + outputSchema: z.record(z.any()).optional(), + payTo: z.string().regex(MixedAddressRegex), + maxTimeoutSeconds: z.number().int(), + asset: z.string().regex(MixedAddressRegex), + extra: z.discriminatedUnion("type", [ + DeferredEvmPaymentRequirementsExtraNewVoucherSchema, + DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, + ]), +}); +export type DeferredEvmPaymentRequirements = z.infer; diff --git a/typescript/packages/x402/src/types/verify/schemes/exact.ts b/typescript/packages/x402/src/types/verify/schemes/exact.ts index 81a8174498..f7e0550e84 100644 --- a/typescript/packages/x402/src/types/verify/schemes/exact.ts +++ b/typescript/packages/x402/src/types/verify/schemes/exact.ts @@ -6,8 +6,9 @@ import { EvmMaxAtomicUnits, } from "../constants"; import { hasMaxLength, isInteger } from "../refiners"; -import { NetworkSchema, x402Versions } from "../.."; import { Base64EncodedRegex } from "../../../shared"; +import { NetworkSchema } from "../../shared"; +import { x402Versions } from "../versions"; export const ExactErrorReasons = [ "invalid_exact_evm_payload_authorization_valid_after", @@ -39,6 +40,8 @@ export const ExactErrorReasons = [ "invalid_exact_svm_payload_transaction_sender_ata_not_found", "invalid_exact_svm_payload_transaction_simulation_failed", "invalid_exact_svm_payload_transaction_transfer_to_incorrect_ata", + "settle_exact_svm_block_height_exceeded", + "settle_exact_svm_transaction_confirmation_timed_out", ] as const; // x402ExactEvmPayloadAuthorization diff --git a/typescript/packages/x402/src/types/verify/versions.ts b/typescript/packages/x402/src/types/verify/versions.ts new file mode 100644 index 0000000000..dca25fddd1 --- /dev/null +++ b/typescript/packages/x402/src/types/verify/versions.ts @@ -0,0 +1 @@ +export const x402Versions = [1] as const; diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index 1c086320b4..34a9b15e51 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -13,10 +13,10 @@ import { DeferredPaymentPayloadSchema, UnsignedDeferredPaymentPayloadSchema, } from "./schemes/deferred"; +import { x402Versions } from "./versions"; // Enums export const schemes = ["exact", "deferred"] as const; -export const x402Versions = [1] as const; export const ErrorReasons = [ "insufficient_funds", "invalid_network", From aac3af496060b4867ccec9c6f06dbf8db0b0c1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 16 Jul 2025 17:19:08 -0300 Subject: [PATCH 004/116] fix: upstream dependencies previously assuming exact as the only scheme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../next-advanced/app/paywall/page.tsx | 8 +- examples/typescript/pnpm-lock.yaml | 6552 ++++++++++------- .../packages/x402/src/types/verify/index.ts | 1 + .../x402/src/types/verify/schemes/index.ts | 2 + .../site/app/facilitator/verify/route.ts | 4 +- 5 files changed, 3876 insertions(+), 2691 deletions(-) create mode 100644 typescript/packages/x402/src/types/verify/schemes/index.ts diff --git a/examples/typescript/fullstack/next-advanced/app/paywall/page.tsx b/examples/typescript/fullstack/next-advanced/app/paywall/page.tsx index 60bfffc622..9f66057337 100644 --- a/examples/typescript/fullstack/next-advanced/app/paywall/page.tsx +++ b/examples/typescript/fullstack/next-advanced/app/paywall/page.tsx @@ -3,7 +3,7 @@ import { Wallet } from "@coinbase/onchainkit/wallet"; import { useState } from "react"; import { verifyPayment } from "../actions"; -import { PaymentRequirements, PaymentPayload } from "x402/types"; +import { PaymentRequirements, PaymentPayload, UnsignedExactPaymentPayloadSchema } from "x402/types"; import { preparePaymentHeader } from "x402/client"; import { getNetworkId } from "x402/shared"; import { exact } from "x402/schemes"; @@ -27,10 +27,8 @@ function PaymentForm({ ); } - const unSignedPaymentHeader = preparePaymentHeader( - address, - 1, - paymentRequirements + const unSignedPaymentHeader = UnsignedExactPaymentPayloadSchema.parse( + preparePaymentHeader(address, 1, paymentRequirements) ); const eip712Data = { diff --git a/examples/typescript/pnpm-lock.yaml b/examples/typescript/pnpm-lock.yaml index 6579798328..9c9e999cdf 100644 --- a/examples/typescript/pnpm-lock.yaml +++ b/examples/typescript/pnpm-lock.yaml @@ -10,10 +10,10 @@ importers: devDependencies: tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) turbo: specifier: ^2.5.0 - version: 2.5.6 + version: 2.5.8 typescript: specifier: ^5.8.3 version: 5.9.2 @@ -22,10 +22,10 @@ importers: dependencies: '@coinbase/cdp-sdk': specifier: ^1.29.0 - version: 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -35,49 +35,49 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/node': specifier: ^22.13.4 - version: 22.17.2 + version: 22.18.6 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) ../../typescript/packages/x402: dependencies: @@ -101,62 +101,62 @@ importers: version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: specifier: ^2.15.6 - version: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + version: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) zod: specifier: ^3.24.2 version: 3.25.76 devDependencies: '@coinbase/onchainkit': specifier: ^0.38.14 - version: 0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + version: 0.38.19(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) '@craftamap/esbuild-plugin-html': specifier: ^0.9.0 - version: 0.9.0(bufferutil@4.0.9)(esbuild@0.25.9)(utf-8-validate@5.0.10) + version: 0.9.0(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@5.0.10) '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/node': specifier: ^22.13.4 - version: 22.17.2 + version: 22.18.6 '@types/react': specifier: ^19 - version: 19.1.10 + version: 19.1.13 '@types/react-dom': specifier: ^19 - version: 19.1.7(@types/react@19.1.10) + version: 19.1.9(@types/react@19.1.13) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@wagmi/connectors': specifier: ^5.8.1 - version: 5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + version: 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76) '@wagmi/core': specifier: ^2.17.1 - version: 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + version: 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) buffer: specifier: ^6.0.3 version: 6.0.3 esbuild: specifier: ^0.25.4 - version: 0.25.9 + version: 0.25.10 eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -168,31 +168,31 @@ importers: version: 19.1.1(react@19.1.1) tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) ../../typescript/packages/x402-axios: dependencies: axios: specifier: ^1.7.9 - version: 1.11.0 + version: 1.12.2 viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -202,55 +202,55 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/node': specifier: ^22.13.4 - version: 22.17.2 + version: 22.18.6 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) ../../typescript/packages/x402-express: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/kit': specifier: ^2.1.1 version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) @@ -259,7 +259,7 @@ importers: version: 4.21.2 viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -269,58 +269,58 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/express': specifier: ^5.0.1 version: 5.0.3 '@types/node': specifier: ^22.13.4 - version: 22.17.2 + version: 22.18.6 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) ../../typescript/packages/x402-fetch: dependencies: viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -330,64 +330,64 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/node': specifier: ^22.13.4 - version: 22.17.2 + version: 22.18.6 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) ../../typescript/packages/x402-hono: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/kit': specifier: ^2.1.1 version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) hono: specifier: ^4.7.1 - version: 4.9.2 + version: 4.9.8 viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -397,64 +397,64 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/node': specifier: ^22.13.4 - version: 22.17.2 + version: 22.18.6 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) ../../typescript/packages/x402-next: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/kit': specifier: ^2.1.1 version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) next: specifier: ^15.0.0 - version: 15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -464,49 +464,49 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/node': specifier: ^22.13.4 - version: 22.17.2 + version: 22.18.6 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) agent: dependencies: @@ -518,22 +518,22 @@ importers: version: 0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@coinbase/agentkit-langchain': specifier: ^0.3.0 - version: 0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + version: 0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) '@langchain/core': specifier: ^0.3.43 - version: 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + version: 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) '@langchain/langgraph': specifier: ^0.2.62 - version: 0.2.74(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76)) + version: 0.2.74(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76)) '@langchain/openai': specifier: ^0.5.2 - version: 0.5.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 0.5.18(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) dotenv: specifier: ^16.4.7 version: 16.6.1 viem: specifier: ^2.26.2 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402-fetch: specifier: workspace:* version: link:../../../typescript/packages/x402-fetch @@ -543,34 +543,34 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/node': specifier: ^22.13.4 - version: 22.17.2 + version: 22.18.6 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.19.2 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.7.3 version: 5.9.2 @@ -579,7 +579,7 @@ importers: dependencies: axios: specifier: ^1.7.9 - version: 1.11.0 + version: 1.12.2 dotenv: specifier: ^16.5.0 version: 16.6.1 @@ -589,31 +589,31 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.7.0 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -622,47 +622,47 @@ importers: dependencies: '@coinbase/cdp-sdk': specifier: ^1.16.0 - version: 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) axios: specifier: ^1.7.9 - version: 1.11.0 + version: 1.12.2 dotenv: specifier: ^16.5.0 version: 16.6.1 viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402-axios: specifier: workspace:* version: link:../../../../typescript/packages/x402-axios devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.7.0 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -671,32 +671,32 @@ importers: dependencies: '@hono/node-server': specifier: ^1.13.8 - version: 1.19.0(hono@4.9.2) + version: 1.19.4(hono@4.9.8) axios: specifier: ^1.7.9 - version: 1.11.0 + version: 1.12.2 dotenv: specifier: ^16.4.5 version: 16.6.1 hono: specifier: ^4.7.2 - version: 4.9.2 + version: 4.9.8 viem: specifier: ^2.23.5 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) x402: specifier: file:../../../../typescript/packages/x402 - version: file:../../typescript/packages/x402(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: file:../../typescript/packages/x402(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) x402-axios: specifier: workspace:* version: link:../../../../typescript/packages/x402-axios devDependencies: '@types/node': specifier: ^22.13.5 - version: 22.17.2 + version: 22.18.6 tsx: specifier: ^4.19.3 - version: 4.20.4 + version: 4.20.5 clients/fetch: dependencies: @@ -709,31 +709,31 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.7.0 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -745,41 +745,41 @@ importers: version: link:../../../typescript/packages/coinbase-x402 axios: specifier: ^1.7.9 - version: 1.11.0 + version: 1.12.2 viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) x402: specifier: workspace:* version: link:../../../typescript/packages/x402 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.7.0 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -791,25 +791,25 @@ importers: version: 0.39.0(encoding@0.1.13) '@hono/node-server': specifier: ^1.14.1 - version: 1.19.0(hono@4.9.2) + version: 1.19.4(hono@4.9.8) '@llamaindex/anthropic': specifier: ^0.3.3 - version: 0.3.23(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30) + version: 0.3.25(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30) '@types/node': specifier: ^22.15.3 - version: 22.17.2 + version: 22.18.6 axios: specifier: ^1.8.4 - version: 1.11.0 + version: 1.12.2 hono: specifier: ^4.7.7 - version: 4.9.2 + version: 4.9.8 llamaindex: specifier: ^0.10.2 version: 0.10.6(encoding@0.1.13)(tree-sitter@0.22.4)(web-tree-sitter@0.24.7)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) viem: specifier: ^2.28.3 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: ^0.2.0 version: 0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) @@ -825,25 +825,25 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -852,7 +852,7 @@ importers: version: 7.3.0(postcss@8.5.6)(typescript@5.9.2) tsx: specifier: ^4.7.0 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -871,31 +871,31 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.7.0 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -907,13 +907,13 @@ importers: version: 0.3.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@hono/node-server': specifier: ^1.11.2 - version: 1.19.0(hono@4.9.2) + version: 1.19.4(hono@4.9.8) dotenv: specifier: ^16.4.5 version: 16.6.1 hono: specifier: ^4.4.0 - version: 4.9.2 + version: 4.9.8 node-fetch: specifier: ^3.3.2 version: 3.3.2 @@ -922,7 +922,7 @@ importers: version: 2.3.2(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) viem: specifier: ^2.13.8 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) x402: specifier: ^0.3.2 version: 0.3.7(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) @@ -935,13 +935,13 @@ importers: devDependencies: '@types/node': specifier: ^20.14.2 - version: 20.19.11 + version: 20.19.17 '@types/node-fetch': specifier: ^2.6.11 version: 2.6.13 tsx: specifier: ^4.11.0 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.4.5 version: 5.9.2 @@ -956,25 +956,25 @@ importers: dependencies: '@coinbase/onchainkit': specifier: latest - version: 0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + version: 1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76) '@coinbase/x402': specifier: latest - version: 0.5.1(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 0.6.4(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) '@farcaster/frame-sdk': specifier: ^0.0.60 version: 0.0.60(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@tanstack/react-query': specifier: ^5 - version: 5.85.5(react@19.1.1) + version: 5.90.2(react@19.1.1) '@upstash/redis': specifier: ^1.34.4 - version: 1.35.3 + version: 1.35.4 '@wagmi/core': specifier: ^2.17.1 - version: 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + version: 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) next: specifier: ^15.3.4 - version: 15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: specifier: ^19.0.0 version: 19.1.1 @@ -986,26 +986,26 @@ importers: version: 2.6.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) viem: specifier: ^2.27.2 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: specifier: ^2.14.11 - version: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + version: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) x402-fetch: specifier: ^0.4.1 - version: 0.4.2(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 0.4.2(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) x402-next: specifier: workspace:* version: link:../../../../typescript/packages/x402-next devDependencies: '@types/node': specifier: ^20.17.30 - version: 20.19.11 + version: 20.19.17 '@types/react': specifier: ^19 - version: 19.1.10 + version: 19.1.13 '@types/react-dom': specifier: ^19 - version: 19.1.7(@types/react@19.1.10) + version: 19.1.9(@types/react@19.1.13) eslint: specifier: ^8 version: 8.57.1 @@ -1047,7 +1047,7 @@ importers: version: 2.2.0(react@19.1.1) next: specifier: ^15.3.4 - version: 15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: specifier: ^19.0.0 version: 19.1.1 @@ -1056,47 +1056,47 @@ importers: version: 19.1.1(react@19.1.1) viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) x402-next: specifier: workspace:* version: link:../../../../typescript/packages/x402-next devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@svgr/webpack': specifier: ^8.1.0 version: 8.1.0(typescript@5.9.2) '@types/node': specifier: ^20 - version: 20.19.11 + version: 20.19.17 '@types/react': specifier: ^19 - version: 19.1.10 + version: 19.1.13 '@types/react-dom': specifier: ^19 - version: 19.1.7(@types/react@19.1.10) + version: 19.1.9(@types/react@19.1.13) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-config-next: specifier: 15.1.7 - version: 15.1.7(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 15.1.7(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) postcss: specifier: ^8 version: 8.5.6 @@ -1120,7 +1120,7 @@ importers: version: 2.2.0(react@19.1.1) next: specifier: ^15.2.4 - version: 15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: specifier: ^19.0.0 version: 19.1.1 @@ -1129,47 +1129,47 @@ importers: version: 19.1.1(react@19.1.1) viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) x402-next: specifier: workspace:* version: link:../../../../typescript/packages/x402-next devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@svgr/webpack': specifier: ^8.1.0 version: 8.1.0(typescript@5.9.2) '@types/node': specifier: ^20 - version: 20.19.11 + version: 20.19.17 '@types/react': specifier: ^19 - version: 19.1.10 + version: 19.1.13 '@types/react-dom': specifier: ^19 - version: 19.1.7(@types/react@19.1.10) + version: 19.1.9(@types/react@19.1.13) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-config-next: specifier: 15.1.7 - version: 15.1.7(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 15.1.7(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) postcss: specifier: ^8 version: 8.5.6 @@ -1187,13 +1187,13 @@ importers: dependencies: '@coinbase/onchainkit': specifier: latest - version: 0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11) '@tanstack/react-query': specifier: ^5 - version: 5.85.5(react@19.1.1) + version: 5.90.2(react@19.1.1) next: specifier: ^15.3.4 - version: 15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: specifier: ^19.0.0 version: 19.1.1 @@ -1202,23 +1202,23 @@ importers: version: 19.1.1(react@19.1.1) viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) wagmi: specifier: ^2.15.6 - version: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + version: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) x402: specifier: workspace:* version: link:../../../../typescript/packages/x402 devDependencies: '@types/node': specifier: ^20 - version: 20.19.11 + version: 20.19.17 '@types/react': specifier: ^19 - version: 19.1.10 + version: 19.1.13 '@types/react-dom': specifier: ^19 - version: 19.1.7(@types/react@19.1.10) + version: 19.1.9(@types/react@19.1.13) eslint: specifier: ^8 version: 8.57.1 @@ -1239,31 +1239,31 @@ importers: dependencies: '@coinbase/cdp-core': specifier: ^0.0.18 - version: 0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) + version: 0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) '@coinbase/cdp-hooks': specifier: ^0.0.18 - version: 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1) + version: 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1) '@coinbase/cdp-react': specifier: ^0.0.18 - version: 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1))(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1))(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@coinbase/x402': specifier: workspace:* version: link:../../../typescript/packages/coinbase-x402 '@modelcontextprotocol/sdk': specifier: ^1.15.1 - version: 1.17.3 + version: 1.18.1 '@radix-ui/react-form': specifier: ^0.1.7 - version: 0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-icons': specifier: ^1.3.2 version: 1.3.2(react@18.3.1) '@radix-ui/themes': specifier: ^3.2.1 - version: 3.2.1(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.2.1(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) axios: specifier: ^1.10.0 - version: 1.11.0 + version: 1.12.2 electron-builder: specifier: ^26.0.12 version: 26.0.12(electron-builder-squirrel-windows@26.0.12) @@ -1278,10 +1278,10 @@ importers: version: 2.0.18(react@18.3.1) turbo: specifier: ^2.5.5 - version: 2.5.6 + version: 2.5.8 viem: specifier: ^2.21.26 - version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) winston: specifier: ^3.17.0 version: 3.17.0 @@ -1296,62 +1296,62 @@ importers: version: 3.25.76 zustand: specifier: ^5.0.6 - version: 5.0.8(@types/react@19.1.10)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) + version: 5.0.8(@types/react@19.1.13)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/node': specifier: ^24.0.13 - version: 24.3.0 + version: 24.5.2 '@types/react': specifier: ^19.1.8 - version: 19.1.10 + version: 19.1.13 '@types/react-dom': specifier: ^19.1.6 - version: 19.1.7(@types/react@19.1.10) + version: 19.1.9(@types/react@19.1.13) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@vitejs/plugin-react': specifier: ^4.7.0 - version: 4.7.0(vite@7.1.3(@types/node@24.3.0)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) + version: 4.7.0(vite@7.1.7(@types/node@24.5.2)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) concurrently: specifier: ^9.2.0 - version: 9.2.0 + version: 9.2.1 electron: specifier: ^37.2.1 - version: 37.3.1 + version: 37.5.1 electron-is-dev: specifier: ^3.0.1 version: 3.0.1 eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.20.3 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.8.3 version: 5.9.2 vite: specifier: ^7.0.5 - version: 7.1.3(@types/node@24.3.0)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + version: 7.1.7(@types/node@24.5.2)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) servers/advanced: dependencies: @@ -1367,28 +1367,28 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/express': specifier: ^5.0.1 version: 5.0.3 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -1397,7 +1397,7 @@ importers: version: 7.3.0(postcss@8.5.6)(typescript@5.9.2) tsx: specifier: ^4.7.0 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -1416,28 +1416,28 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/express': specifier: ^5.0.1 version: 5.0.3 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -1446,7 +1446,7 @@ importers: version: 7.3.0(postcss@8.5.6)(typescript@5.9.2) tsx: specifier: ^4.7.0 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -1455,38 +1455,38 @@ importers: dependencies: '@hono/node-server': specifier: ^1.13.8 - version: 1.19.0(hono@4.9.2) + version: 1.19.4(hono@4.9.8) dotenv: specifier: ^16.4.7 version: 16.6.1 hono: specifier: ^4.7.1 - version: 4.9.2 + version: 4.9.8 x402-hono: specifier: workspace:* version: link:../../../../typescript/packages/x402-hono devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -1495,7 +1495,7 @@ importers: version: 7.3.0(postcss@8.5.6)(typescript@5.9.2) tsx: specifier: ^4.7.0 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -1517,28 +1517,28 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.33.0 + version: 9.36.0 '@types/express': specifier: ^5.0.1 version: 5.0.3 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.33.0(jiti@1.21.7) + version: 9.36.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -1547,7 +1547,7 @@ importers: version: 7.3.0(postcss@8.5.6)(typescript@5.9.2) tsx: specifier: ^4.7.0 - version: 4.20.4 + version: 4.20.5 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -1566,8 +1566,8 @@ packages: '@adraffy/ens-normalize@1.10.1': resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} - '@adraffy/ens-normalize@1.11.0': - resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + '@adraffy/ens-normalize@1.11.1': + resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} @@ -1577,10 +1577,6 @@ packages: resolution: {integrity: sha512-43+Psr16UY+xh7MWn/lZyHTQiOkn0GlKtsfj9IynfCFW3jac8R3WoP6GaIqyErmeTIBq48rURZ7KFfSiRrmNTA==} engines: {node: '>=18'} - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - '@anthropic-ai/sdk@0.39.0': resolution: {integrity: sha512-eMyDIPRZbt1CCLErRCi3exlAvNkBtRe+kW5vvJyef93PmNr/clstYgHhtvmkxN82nlKgzyGPCyGxrm0JQ1ZIdg==} @@ -1598,20 +1594,20 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/types@3.862.0': - resolution: {integrity: sha512-Bei+RL0cDxxV+lW2UezLbCYYNeJm6Nzee0TpW0FfyTRBhH9C1XQh4+x+IClriXvgBnRquTMMYsmJfvx8iyLKrg==} + '@aws-sdk/types@3.893.0': + resolution: {integrity: sha512-Aht1nn5SnA0N+Tjv0dzhAY7CQbxVtmq1bBR6xI0MhG7p2XYVh1wXuKTzrldEvQWwA3odOYunAfT9aBiKZx9qIg==} engines: {node: '>=18.0.0'} '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.0': - resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} + '@babel/compat-data@7.28.4': + resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.3': - resolution: {integrity: sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==} + '@babel/core@7.28.4': + resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} engines: {node: '>=6.9.0'} '@babel/generator@7.28.3': @@ -1701,12 +1697,12 @@ packages: resolution: {integrity: sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.3': - resolution: {integrity: sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==} + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.3': - resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} + '@babel/parser@7.28.4': + resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} engines: {node: '>=6.0.0'} hasBin: true @@ -1800,8 +1796,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.28.0': - resolution: {integrity: sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==} + '@babel/plugin-transform-block-scoping@7.28.4': + resolution: {integrity: sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1818,8 +1814,8 @@ packages: peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.28.3': - resolution: {integrity: sha512-DoEWC5SuxuARF2KdKmGUq3ghfPMO6ZzR12Dnp5gubwbeWJo4dbNWXJPVlwvh4Zlq6Z7YVvL8VFxeSOJgjsx4Sg==} + '@babel/plugin-transform-classes@7.28.4': + resolution: {integrity: sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1962,8 +1958,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.28.0': - resolution: {integrity: sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==} + '@babel/plugin-transform-object-rest-spread@7.28.4': + resolution: {integrity: sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -2052,8 +2048,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.28.3': - resolution: {integrity: sha512-K3/M/a4+ESb5LEldjQb+XSrpY0nF+ZBFlTCbSnKaYAMfD8v33O6PMs4uYnOk19HlcsI8WMu3McdFPTiQHF/1/A==} + '@babel/plugin-transform-regenerator@7.28.4': + resolution: {integrity: sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -2153,20 +2149,20 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.28.3': - resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==} + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} engines: {node: '>=6.9.0'} '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.3': - resolution: {integrity: sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==} + '@babel/traverse@7.28.4': + resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + '@babel/types@7.28.4': + resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} '@base-org/account@1.1.1': @@ -2202,8 +2198,8 @@ packages: '@coinbase/cdp-hooks': ^0.0.18 react: '>=18.2.0' - '@coinbase/cdp-sdk@1.36.0': - resolution: {integrity: sha512-q+8KnNEZW7mFKdCw0FsZKQ0CuxP5B0JNCkj4Ucmspjbe/EM8ZXVNh1SQMISZCu7gq9KY4bJDmpGqddwtkSGL5Q==} + '@coinbase/cdp-sdk@1.38.2': + resolution: {integrity: sha512-S7+xKeZGGi+zc1PotTeQ5Pvn5a0e4ikT+iMm8pPfPjObNlDEUKLei4cmRHON1wXgql0oDXn30YKTo1LQWxXvDw==} '@coinbase/coinbase-sdk@0.20.0': resolution: {integrity: sha512-OoMMktKbjmeEwtwQCK3kIIoX5M+hNelxAGX5Llymvw6bmyrMDaEBZ/Myga9kaLJ+7Hi5Y4jPDy4Cy2MGxxXg6w==} @@ -2214,6 +2210,14 @@ packages: react: ^18 || ^19 react-dom: ^18 || ^19 + '@coinbase/onchainkit@1.1.0': + resolution: {integrity: sha512-qoyfeGb/dwD+Rm38+3o9dIP9UcLIuzJEr5STIPXvEr5aP3aqrmFKBLRHUFVcWvLVQGkHQdpgVkWkD6a+Mh3l7A==} + peerDependencies: + react: ^19 + react-dom: ^19 + viem: ^2.27 + wagmi: ^2.16 + '@coinbase/wallet-sdk@3.9.3': resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} @@ -2223,8 +2227,8 @@ packages: '@coinbase/x402@0.3.8': resolution: {integrity: sha512-qEjxQRefXCyTfxXf4LJtB5CQZAVqjVulbol5fjcYMrA6buA1ZCq7J+l2IJVVYfeJTv70s5atLEi35xxWNobLTQ==} - '@coinbase/x402@0.5.1': - resolution: {integrity: sha512-zKT0gFQ6LR8UKasVtUeAnJVHEdJUAHOicxd3VumR0rxKYWnRU/yaXVQ6iq5XZvtMAs+rfpyTUbKAgIyPfV9VxQ==} + '@coinbase/x402@0.6.4': + resolution: {integrity: sha512-T0tNU8/oZ64GaKC3dbGcOFHqYO0BjII/uZeC/tAS9HOqhWBvewhoa0rzPzaE8SHeKOIwX2YpbFXdG0Hyh0d4mw==} '@colors/colors@1.6.0': resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} @@ -2236,8 +2240,8 @@ packages: peerDependencies: esbuild: '>=0.15.10' - '@csstools/color-helpers@5.0.2': - resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} engines: {node: '>=18'} '@csstools/css-calc@2.1.4': @@ -2247,8 +2251,8 @@ packages: '@csstools/css-parser-algorithms': ^3.0.5 '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-color-parser@3.0.10': - resolution: {integrity: sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==} + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} engines: {node: '>=18'} peerDependencies: '@csstools/css-parser-algorithms': ^3.0.5 @@ -2324,14 +2328,14 @@ packages: engines: {node: '>=14.14'} hasBin: true - '@emnapi/core@1.4.5': - resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==} + '@emnapi/core@1.5.0': + resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} - '@emnapi/runtime@1.4.5': - resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} + '@emnapi/runtime@1.5.0': + resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} - '@emnapi/wasi-threads@1.0.4': - resolution: {integrity: sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==} + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} '@es-joy/jsdoccomment@0.50.2': resolution: {integrity: sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==} @@ -2343,8 +2347,8 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.25.9': - resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} + '@esbuild/aix-ppc64@0.25.10': + resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -2355,8 +2359,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.9': - resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} + '@esbuild/android-arm64@0.25.10': + resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -2367,8 +2371,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.9': - resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} + '@esbuild/android-arm@0.25.10': + resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -2379,8 +2383,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.9': - resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} + '@esbuild/android-x64@0.25.10': + resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -2391,8 +2395,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.9': - resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} + '@esbuild/darwin-arm64@0.25.10': + resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -2403,8 +2407,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.9': - resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} + '@esbuild/darwin-x64@0.25.10': + resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -2415,8 +2419,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.9': - resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} + '@esbuild/freebsd-arm64@0.25.10': + resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -2427,8 +2431,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.9': - resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} + '@esbuild/freebsd-x64@0.25.10': + resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -2439,8 +2443,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.9': - resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} + '@esbuild/linux-arm64@0.25.10': + resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -2451,8 +2455,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.9': - resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} + '@esbuild/linux-arm@0.25.10': + resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -2463,8 +2467,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.9': - resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} + '@esbuild/linux-ia32@0.25.10': + resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -2475,8 +2479,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.9': - resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} + '@esbuild/linux-loong64@0.25.10': + resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -2487,8 +2491,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.9': - resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} + '@esbuild/linux-mips64el@0.25.10': + resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -2499,8 +2503,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.9': - resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} + '@esbuild/linux-ppc64@0.25.10': + resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -2511,8 +2515,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.9': - resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} + '@esbuild/linux-riscv64@0.25.10': + resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -2523,8 +2527,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.9': - resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} + '@esbuild/linux-s390x@0.25.10': + resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -2535,14 +2539,14 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.9': - resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} + '@esbuild/linux-x64@0.25.10': + resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.9': - resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} + '@esbuild/netbsd-arm64@0.25.10': + resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -2553,14 +2557,14 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.9': - resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} + '@esbuild/netbsd-x64@0.25.10': + resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.9': - resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} + '@esbuild/openbsd-arm64@0.25.10': + resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -2571,14 +2575,14 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.9': - resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} + '@esbuild/openbsd-x64@0.25.10': + resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.9': - resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} + '@esbuild/openharmony-arm64@0.25.10': + resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] @@ -2589,8 +2593,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.9': - resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} + '@esbuild/sunos-x64@0.25.10': + resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -2601,8 +2605,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.9': - resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} + '@esbuild/win32-arm64@0.25.10': + resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -2613,8 +2617,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.9': - resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} + '@esbuild/win32-ia32@0.25.10': + resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -2625,14 +2629,14 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.25.9': - resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} + '@esbuild/win32-x64@0.25.10': + resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -2665,8 +2669,8 @@ packages: resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/js@9.33.0': - resolution: {integrity: sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==} + '@eslint/js@9.36.0': + resolution: {integrity: sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -2699,15 +2703,15 @@ packages: '@farcaster/frame-sdk@0.0.60': resolution: {integrity: sha512-MHQwdFT1VPe3kS0NvnORBPb/DQXr8qpdSDgIgfrdVCB8byQ5uFELlr3gQMuFYFyLFQVXgbMl75z8O6+hvorqow==} - '@farcaster/frame-sdk@0.1.9': - resolution: {integrity: sha512-r5cAKgHn4w8Q1jaCi84uKqItfNRd6h8Lk0YyQaz5kMoEIeJ4C0gXPpyqKPYP2TVDFuvaexg2KvzCO2CQdygWyQ==} + '@farcaster/frame-sdk@0.1.10': + resolution: {integrity: sha512-4CtBkzHIGg7NVUbVZfgy6UiIeSqn0rx7vmwvOJ4pNRQoLG5guPkHKv9vc3D515aCVSATvrZXRT97xjss5kuN+Q==} engines: {node: '>=22.11.0'} - '@farcaster/miniapp-core@0.3.8': - resolution: {integrity: sha512-LaRG1L3lxHqo5pP/E2CX9hNqusR0C8hX3QTV2+hzmQJz6IGvmSpH6Q9ivlLyDfbdqokiMFo5Y3Z1EX1zBHMEQQ==} + '@farcaster/miniapp-core@0.3.9': + resolution: {integrity: sha512-7k2AHYycFABUEQFHGqsuZr6P6UQOE2WO4/Qj/kQ1ydKA8QjrWxO4HjiPfnTdvqH0xOKtdavbFOV5lK5bDLkemw==} - '@farcaster/miniapp-sdk@0.1.9': - resolution: {integrity: sha512-hn0dlIy0JP2Hx6PgKcn9bjYwyPS/SQgYJ/a0qjzG8ZsDfUdjsMPf3yI/jicBipTml/UUoKcbqXM68fsrsbNMKA==} + '@farcaster/miniapp-sdk@0.1.10': + resolution: {integrity: sha512-ueoEAH3N7hIrV+L9pXdLJZpOY1GsOuwKN7MckouSEWY98H5A7KVajyGmGSDDVzjRWpu7Vndu4NZUHoOhF4nTOA==} '@farcaster/miniapp-wagmi-connector@1.0.0': resolution: {integrity: sha512-vMRZbekUUctnAUvBFhNoEsJlujRRdxop94fDy5LrKiRR9ax0wtp8gCvLYO+LpaP2PtGs0HFpRwlHNDJWvBR8bg==} @@ -2729,15 +2733,21 @@ packages: '@floating-ui/core@1.7.3': resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} - '@floating-ui/dom@1.7.3': - resolution: {integrity: sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==} + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} - '@floating-ui/react-dom@2.1.5': - resolution: {integrity: sha512-HDO/1/1oH9fjj4eLgegrlH3dklZpHtUYYFiVwMUwfGvk9jWDRWqkklA2/NFScknrcNSspbV868WjXORvreDX+Q==} + '@floating-ui/react-dom@2.1.6': + resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' + '@floating-ui/react@0.27.16': + resolution: {integrity: sha512-9O8N4SeG2z++TSM8QA/KTeKFBVCNEz/AGS7gWPJf6KFRzmRWixFRnCnkPHRDwSVZW6QPDO6uT0P2SpWNKCc9/g==} + peerDependencies: + react: '>=17.0.0' + react-dom: '>=17.0.0' + '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} @@ -2759,8 +2769,8 @@ packages: peerDependencies: react: '>= 16 || ^19.0.0-rc' - '@hono/node-server@1.19.0': - resolution: {integrity: sha512-1k8/8OHf5VIymJEcJyVksFpT+AQ5euY0VA5hUkCnlKpD4mr8FSbvXaHblxeTTEr90OaqWzAkQaqD80qHZQKxBA==} + '@hono/node-server@1.19.4': + resolution: {integrity: sha512-AWKQZ/YkHUBSHeL/5Ld8FWgUs6wFf4TxGYxqp9wLZxRdFuHBpXmgOq+CuDoL4vllkZLzovCf5HBJnypiy3EtHA==} engines: {node: '>=18.14.1'} peerDependencies: hono: ^4 @@ -2781,8 +2791,8 @@ packages: resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} engines: {node: '>=18.18.0'} '@humanwhocodes/config-array@0.13.0': @@ -2798,132 +2808,132 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.3': resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@img/sharp-darwin-arm64@0.34.3': - resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} + '@img/colour@1.0.0': + resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.4': + resolution: {integrity: sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.34.3': - resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} + '@img/sharp-darwin-x64@0.34.4': + resolution: {integrity: sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.0': - resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} + '@img/sharp-libvips-darwin-arm64@1.2.3': + resolution: {integrity: sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.0': - resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} + '@img/sharp-libvips-darwin-x64@1.2.3': + resolution: {integrity: sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.2.0': - resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} + '@img/sharp-libvips-linux-arm64@1.2.3': + resolution: {integrity: sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm@1.2.0': - resolution: {integrity: sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==} + '@img/sharp-libvips-linux-arm@1.2.3': + resolution: {integrity: sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-ppc64@1.2.0': - resolution: {integrity: sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==} + '@img/sharp-libvips-linux-ppc64@1.2.3': + resolution: {integrity: sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==} cpu: [ppc64] os: [linux] - '@img/sharp-libvips-linux-s390x@1.2.0': - resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} + '@img/sharp-libvips-linux-s390x@1.2.3': + resolution: {integrity: sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==} cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-x64@1.2.0': - resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} + '@img/sharp-libvips-linux-x64@1.2.3': + resolution: {integrity: sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==} cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': - resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} + '@img/sharp-libvips-linuxmusl-arm64@1.2.3': + resolution: {integrity: sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.2.0': - resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} + '@img/sharp-libvips-linuxmusl-x64@1.2.3': + resolution: {integrity: sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==} cpu: [x64] os: [linux] - '@img/sharp-linux-arm64@0.34.3': - resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} + '@img/sharp-linux-arm64@0.34.4': + resolution: {integrity: sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm@0.34.3': - resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} + '@img/sharp-linux-arm@0.34.4': + resolution: {integrity: sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - '@img/sharp-linux-ppc64@0.34.3': - resolution: {integrity: sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==} + '@img/sharp-linux-ppc64@0.34.4': + resolution: {integrity: sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] - '@img/sharp-linux-s390x@0.34.3': - resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} + '@img/sharp-linux-s390x@0.34.4': + resolution: {integrity: sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] - '@img/sharp-linux-x64@0.34.3': - resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} + '@img/sharp-linux-x64@0.34.4': + resolution: {integrity: sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.3': - resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} + '@img/sharp-linuxmusl-arm64@0.34.4': + resolution: {integrity: sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-x64@0.34.3': - resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} + '@img/sharp-linuxmusl-x64@0.34.4': + resolution: {integrity: sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.34.3': - resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} + '@img/sharp-wasm32@0.34.4': + resolution: {integrity: sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-win32-arm64@0.34.3': - resolution: {integrity: sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==} + '@img/sharp-win32-arm64@0.34.4': + resolution: {integrity: sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [win32] - '@img/sharp-win32-ia32@0.34.3': - resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} + '@img/sharp-win32-ia32@0.34.4': + resolution: {integrity: sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.34.3': - resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} + '@img/sharp-win32-x64@0.34.4': + resolution: {integrity: sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] @@ -2943,6 +2953,9 @@ packages: '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -2950,14 +2963,14 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.30': - resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} '@jup-ag/api@6.0.44': resolution: {integrity: sha512-C6oYi+wvNi07VlmWhT8+ZDMqTJuF+MiHuNBE65cYuBH6C4l0JfwpXaj6mKazAdVqVFWgngr3s2+0tdF5nDH4tA==} - '@langchain/core@0.3.72': - resolution: {integrity: sha512-WsGWVZYnlKffj2eEfDocPNiaTRoxyYiLSQdQ7oxZvxGZBqo/90vpjbC33UGK1uPNBM4kT+pkdaol/MnvKUh8TQ==} + '@langchain/core@0.3.77': + resolution: {integrity: sha512-aqXHea9xfpVn6VoCq9pjujwFqrh3vw3Fgm9KFUZJ1cF7Bx5HI62DvQPw8LlRB3NB4dhwBBA1ldAVkkkd1du8nA==} engines: {node: '>=18'} '@langchain/langgraph-checkpoint@0.0.18': @@ -2966,8 +2979,8 @@ packages: peerDependencies: '@langchain/core': '>=0.2.31 <0.4.0' - '@langchain/langgraph-sdk@0.0.109': - resolution: {integrity: sha512-UpjL0c681CJqvKxgWD8o9fwUXRZzcDfsz8EcJ2PkXFxQFKRLe4QKZMtBr4OKFTR94pJtlOuTVla4OV5I5w+mdQ==} + '@langchain/langgraph-sdk@0.0.112': + resolution: {integrity: sha512-/9W5HSWCqYgwma6EoOspL4BGYxGxeJP6lIquPSF4FA0JlKopaUv58ucZC3vAgdJyCgg6sorCIV/qg7SGpEcCLw==} peerDependencies: '@langchain/core': '>=0.2.31 <0.4.0' react: ^18 || ^19 @@ -3002,10 +3015,10 @@ packages: '@lit/reactive-element@2.1.1': resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} - '@llamaindex/anthropic@0.3.23': - resolution: {integrity: sha512-4qvRZ8cBasRdLliN5KMi1diSn+9lNFTOaUroCSwMAivRl97R1HVd+ZRfXqmorkoB2aYpG4rAZ9ycIgRNUctX8g==} + '@llamaindex/anthropic@0.3.25': + resolution: {integrity: sha512-qrRh2ReRUY/pwApZjaX6gpUQRZxx16UcMoZLuBWP+pySzEr0jvZSq9guYmLRbQMv1xgr3SWoPjulMR+AEh7Dgg==} peerDependencies: - '@llamaindex/core': 0.6.20 + '@llamaindex/core': 0.6.22 '@llamaindex/env': 0.1.30 '@llamaindex/cloud@4.0.7': @@ -3099,8 +3112,11 @@ packages: resolution: {integrity: sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==} engines: {node: '>=12.0.0'} - '@metamask/sdk-communication-layer@0.32.0': - resolution: {integrity: sha512-dmj/KFjMi1fsdZGIOtbhxdg3amxhKL/A5BqSU4uh/SyDKPub/OT+x5pX8bGjpTL1WPWY/Q0OIlvFyX3VWnT06Q==} + '@metamask/sdk-analytics@0.0.5': + resolution: {integrity: sha512-fDah+keS1RjSUlC8GmYXvx6Y26s3Ax1U9hGpWb6GSY5SAdmTSIqp2CvYy6yW0WgLhnYhW+6xERuD0eVqV63QIQ==} + + '@metamask/sdk-communication-layer@0.33.1': + resolution: {integrity: sha512-0bI9hkysxcfbZ/lk0T2+aKVo1j0ynQVTuB3sJ5ssPWlz+Z3VwveCkP1O7EVu1tsVVCb0YV5WxK9zmURu2FIiaA==} peerDependencies: cross-fetch: ^4.0.0 eciesjs: '*' @@ -3108,18 +3124,18 @@ packages: readable-stream: ^3.6.2 socket.io-client: ^4.5.1 - '@metamask/sdk-install-modal-web@0.32.0': - resolution: {integrity: sha512-TFoktj0JgfWnQaL3yFkApqNwcaqJ+dw4xcnrJueMP3aXkSNev2Ido+WVNOg4IIMxnmOrfAC9t0UJ0u/dC9MjOQ==} + '@metamask/sdk-install-modal-web@0.32.1': + resolution: {integrity: sha512-MGmAo6qSjf1tuYXhCu2EZLftq+DSt5Z7fsIKr2P+lDgdTPWgLfZB1tJKzNcwKKOdf6q9Qmmxn7lJuI/gq5LrKw==} - '@metamask/sdk@0.32.0': - resolution: {integrity: sha512-WmGAlP1oBuD9hk4CsdlG1WJFuPtYJY+dnTHJMeCyohTWD2GgkcLMUUuvu9lO1/NVzuOoSi1OrnjbuY1O/1NZ1g==} + '@metamask/sdk@0.33.1': + resolution: {integrity: sha512-1mcOQVGr9rSrVcbKPNVzbZ8eCl1K0FATsYH3WJ/MH4WcZDWGECWrXJPNMZoEAkLxWiMe8jOQBumg2pmcDa9zpQ==} '@metamask/superstruct@3.2.1': resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==} engines: {node: '>=16.0.0'} - '@metamask/utils@11.4.2': - resolution: {integrity: sha512-TygCcGmUbhmpxjYMm+mx68kRiJ80jYV54/Aa8gUFBv4cTX7ulX2XZKr8CJoJAw3K3FN5ZvCRmU0IzWZFaonwhA==} + '@metamask/utils@11.8.1': + resolution: {integrity: sha512-DIbsNUyqWLFgqJlZxi1OOCMYvI23GqFCvNJAtzv8/WXWzJfnJnvp1M24j7VvUe3URBi3S86UgQ7+7aWU9p/cnQ==} engines: {node: ^18.18 || ^20.14 || >=22} '@metamask/utils@5.0.2': @@ -3134,15 +3150,15 @@ packages: resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} engines: {node: '>=16.0.0'} - '@modelcontextprotocol/sdk@1.17.3': - resolution: {integrity: sha512-JPwUKWSsbzx+DLFznf/QZ32Qa+ptfbUlHhRLrBQBAFu9iI1iYvizM4p+zhhRDceSsPutXp4z+R/HPVphlIiclg==} + '@modelcontextprotocol/sdk@1.18.1': + resolution: {integrity: sha512-d//GE8/Yh7aC3e7p+kZG8JqqEAwwDUmAfvH1quogtbk+ksS6E0RR6toKKESPYYZVre0meqkJb27zb+dhqE9Sgw==} engines: {node: '>=18'} '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - '@next/env@15.5.0': - resolution: {integrity: sha512-sDaprBAfzCQiOgo2pO+LhnV0Wt2wBgartjrr+dpcTORYVnnXD0gwhHhiiyIih9hQbq+JnbqH4odgcFWhqCGidw==} + '@next/env@15.5.4': + resolution: {integrity: sha512-27SQhYp5QryzIT5uO8hq99C69eLQ7qkzkDPsk3N+GuS2XgOgoYEeOav7Pf8Tn4drECOVDsDg8oj+/DVy8qQL2A==} '@next/eslint-plugin-next@15.1.7': resolution: {integrity: sha512-kRP7RjSxfTO13NE317ek3mSGzoZlI33nc/i5hs1KaWpK+egs85xg0DJ4p32QEiHnR0mVjuUfhRIun7awqfL7pQ==} @@ -3150,50 +3166,50 @@ packages: '@next/eslint-plugin-next@15.3.3': resolution: {integrity: sha512-VKZJEiEdpKkfBmcokGjHu0vGDG+8CehGs90tBEy/IDoDDKGngeyIStt2MmE5FYNyU9BhgR7tybNWTAJY/30u+Q==} - '@next/swc-darwin-arm64@15.5.0': - resolution: {integrity: sha512-v7Jj9iqC6enxIRBIScD/o0lH7QKvSxq2LM8UTyqJi+S2w2QzhMYjven4vgu/RzgsdtdbpkyCxBTzHl/gN5rTRg==} + '@next/swc-darwin-arm64@15.5.4': + resolution: {integrity: sha512-nopqz+Ov6uvorej8ndRX6HlxCYWCO3AHLfKK2TYvxoSB2scETOcfm/HSS3piPqc3A+MUgyHoqE6je4wnkjfrOA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@15.5.0': - resolution: {integrity: sha512-s2Nk6ec+pmYmAb/utawuURy7uvyYKDk+TRE5aqLRsdnj3AhwC9IKUBmhfnLmY/+P+DnwqpeXEFIKe9tlG0p6CA==} + '@next/swc-darwin-x64@15.5.4': + resolution: {integrity: sha512-QOTCFq8b09ghfjRJKfb68kU9k2K+2wsC4A67psOiMn849K9ZXgCSRQr0oVHfmKnoqCbEmQWG1f2h1T2vtJJ9mA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@15.5.0': - resolution: {integrity: sha512-mGlPJMZReU4yP5fSHjOxiTYvZmwPSWn/eF/dcg21pwfmiUCKS1amFvf1F1RkLHPIMPfocxLViNWFvkvDB14Isg==} + '@next/swc-linux-arm64-gnu@15.5.4': + resolution: {integrity: sha512-eRD5zkts6jS3VfE/J0Kt1VxdFqTnMc3QgO5lFE5GKN3KDI/uUpSyK3CjQHmfEkYR4wCOl0R0XrsjpxfWEA++XA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.5.0': - resolution: {integrity: sha512-biWqIOE17OW/6S34t1X8K/3vb1+svp5ji5QQT/IKR+VfM3B7GvlCwmz5XtlEan2ukOUf9tj2vJJBffaGH4fGRw==} + '@next/swc-linux-arm64-musl@15.5.4': + resolution: {integrity: sha512-TOK7iTxmXFc45UrtKqWdZ1shfxuL4tnVAOuuJK4S88rX3oyVV4ZkLjtMT85wQkfBrOOvU55aLty+MV8xmcJR8A==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@15.5.0': - resolution: {integrity: sha512-zPisT+obYypM/l6EZ0yRkK3LEuoZqHaSoYKj+5jiD9ESHwdr6QhnabnNxYkdy34uCigNlWIaCbjFmQ8FY5AlxA==} + '@next/swc-linux-x64-gnu@15.5.4': + resolution: {integrity: sha512-7HKolaj+481FSW/5lL0BcTkA4Ueam9SPYWyN/ib/WGAFZf0DGAN8frNpNZYFHtM4ZstrHZS3LY3vrwlIQfsiMA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.5.0': - resolution: {integrity: sha512-+t3+7GoU9IYmk+N+FHKBNFdahaReoAktdOpXHFIPOU1ixxtdge26NgQEEkJkCw2dHT9UwwK5zw4mAsURw4E8jA==} + '@next/swc-linux-x64-musl@15.5.4': + resolution: {integrity: sha512-nlQQ6nfgN0nCO/KuyEUwwOdwQIGjOs4WNMjEUtpIQJPR2NUfmGpW2wkJln1d4nJ7oUzd1g4GivH5GoEPBgfsdw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@15.5.0': - resolution: {integrity: sha512-d8MrXKh0A+c9DLiy1BUFwtg3Hu90Lucj3k6iKTUdPOv42Ve2UiIG8HYi3UAb8kFVluXxEfdpCoPPCSODk5fDcw==} + '@next/swc-win32-arm64-msvc@15.5.4': + resolution: {integrity: sha512-PcR2bN7FlM32XM6eumklmyWLLbu2vs+D7nJX8OAIoWy69Kef8mfiN4e8TUv2KohprwifdpFKPzIP1njuCjD0YA==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@15.5.0': - resolution: {integrity: sha512-Fe1tGHxOWEyQjmygWkkXSwhFcTJuimrNu52JEuwItrKJVV4iRjbWp9I7zZjwqtiNnQmxoEvoisn8wueFLrNpvQ==} + '@next/swc-win32-x64-msvc@15.5.4': + resolution: {integrity: sha512-1ur2tSHZj8Px/KMAthmuI9FMp/YFusMMGoRNJaRZMOlSkgvLjzosSdQI0cJAKogdHl3qXUQKL9MGaYvKwA7DXg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -3220,8 +3236,8 @@ packages: resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} engines: {node: ^14.21.3 || >=16} - '@noble/curves@1.9.6': - resolution: {integrity: sha512-GIKz/j99FRthB8icyJQA51E8Uk5hXmdyThjgQXRKiv9h0zeRlzSCLIzFw6K1LotZ3XuB7yzlf76qk7uBmTdFqA==} + '@noble/curves@1.9.1': + resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} engines: {node: ^14.21.3 || >=16} '@noble/curves@1.9.7': @@ -3289,14 +3305,14 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@privy-io/api-base@1.6.0': - resolution: {integrity: sha512-ftlqjFw0Ww7Xn6Ad/1kEUsXRfKqNdmJYKat4ryJl2uPh60QXXlPfnf4y17dDFHJlnVb7qY10cCvKVz5ev5gAeg==} + '@privy-io/api-base@1.7.0': + resolution: {integrity: sha512-ji6ARQAAuW/FzRTgft9NCjRuouWX9t+J7JMmvLPsnXQJDFEV9mqh4sWXZhQ8ddTq/iDZ4z/yz1ORJqN8bYAi4Q==} - '@privy-io/public-api@2.43.1': - resolution: {integrity: sha512-zhGBTghZiwnqdA4YvrXXM7fsz3fWUltSkxNdnQTqKGb/IfV8aZ14ryuWvD4v5oPJGtqVcwKRfdDmW8TMPGZHog==} + '@privy-io/public-api@2.45.2': + resolution: {integrity: sha512-TSuaFq65PPInb0CBJ9dO/vLh4u4oWXVpv5KxShbVsuaArZ8lig+Orl/HUR1Hri6643zXoBqWlWx9wDt4MQvz9A==} - '@privy-io/server-auth@1.31.1': - resolution: {integrity: sha512-w0DT0VZCPcXa/Mxqzo7fhXoInX5i4J5BgvzjNsdtMuovgR790kMx/9+K/rSlgtQ/25/B7oDjoIk/f8kd5Ps6mA==} + '@privy-io/server-auth@1.32.5': + resolution: {integrity: sha512-e087vImrFHP4yAMx8alyCeCm6gk2JG/q7eSklFoST5mPTUV9TGKx7XNIyKOQQHxwKMpk5SBVIlkyJcqg3CuxSw==} peerDependencies: ethers: ^6 viem: ^2.24.1 @@ -4049,103 +4065,113 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rollup/rollup-android-arm-eabi@4.46.4': - resolution: {integrity: sha512-B2wfzCJ+ps/OBzRjeds7DlJumCU3rXMxJJS1vzURyj7+KBHGONm7c9q1TfdBl4vCuNMkDvARn3PBl2wZzuR5mw==} + '@rollup/rollup-android-arm-eabi@4.52.2': + resolution: {integrity: sha512-o3pcKzJgSGt4d74lSZ+OCnHwkKBeAbFDmbEm5gg70eA8VkyCuC/zV9TwBnmw6VjDlRdF4Pshfb+WE9E6XY1PoQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.46.4': - resolution: {integrity: sha512-FGJYXvYdn8Bs6lAlBZYT5n+4x0ciEp4cmttsvKAZc/c8/JiPaQK8u0c/86vKX8lA7OY/+37lIQSe0YoAImvBAA==} + '@rollup/rollup-android-arm64@4.52.2': + resolution: {integrity: sha512-cqFSWO5tX2vhC9hJTK8WAiPIm4Q8q/cU8j2HQA0L3E1uXvBYbOZMhE2oFL8n2pKB5sOCHY6bBuHaRwG7TkfJyw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.46.4': - resolution: {integrity: sha512-/9qwE/BM7ATw/W/OFEMTm3dmywbJyLQb4f4v5nmOjgYxPIGpw7HaxRi6LnD4Pjn/q7k55FGeHe1/OD02w63apA==} + '@rollup/rollup-darwin-arm64@4.52.2': + resolution: {integrity: sha512-vngduywkkv8Fkh3wIZf5nFPXzWsNsVu1kvtLETWxTFf/5opZmflgVSeLgdHR56RQh71xhPhWoOkEBvbehwTlVA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.46.4': - resolution: {integrity: sha512-QkWfNbeRuzFnv2d0aPlrzcA3Ebq2mE8kX/5Pl7VdRShbPBjSnom7dbT8E3Jmhxo2RL784hyqGvR5KHavCJQciw==} + '@rollup/rollup-darwin-x64@4.52.2': + resolution: {integrity: sha512-h11KikYrUCYTrDj6h939hhMNlqU2fo/X4NB0OZcys3fya49o1hmFaczAiJWVAFgrM1NCP6RrO7lQKeVYSKBPSQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.46.4': - resolution: {integrity: sha512-+ToyOMYnSfV8D+ckxO6NthPln/PDNp1P6INcNypfZ7muLmEvPKXqduUiD8DlJpMMT8LxHcE5W0dK9kXfJke9Zw==} + '@rollup/rollup-freebsd-arm64@4.52.2': + resolution: {integrity: sha512-/eg4CI61ZUkLXxMHyVlmlGrSQZ34xqWlZNW43IAU4RmdzWEx0mQJ2mN/Cx4IHLVZFL6UBGAh+/GXhgvGb+nVxw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.46.4': - resolution: {integrity: sha512-cGT6ey/W+sje6zywbLiqmkfkO210FgRz7tepWAzzEVgQU8Hn91JJmQWNqs55IuglG8sJdzk7XfNgmGRtcYlo1w==} + '@rollup/rollup-freebsd-x64@4.52.2': + resolution: {integrity: sha512-QOWgFH5X9+p+S1NAfOqc0z8qEpJIoUHf7OWjNUGOeW18Mx22lAUOiA9b6r2/vpzLdfxi/f+VWsYjUOMCcYh0Ng==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.46.4': - resolution: {integrity: sha512-9fhTJyOb275w5RofPSl8lpr4jFowd+H4oQKJ9XTYzD1JWgxdZKE8bA6d4npuiMemkecQOcigX01FNZNCYnQBdA==} + '@rollup/rollup-linux-arm-gnueabihf@4.52.2': + resolution: {integrity: sha512-kDWSPafToDd8LcBYd1t5jw7bD5Ojcu12S3uT372e5HKPzQt532vW+rGFFOaiR0opxePyUkHrwz8iWYEyH1IIQA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.46.4': - resolution: {integrity: sha512-+6kCIM5Zjvz2HwPl/udgVs07tPMIp1VU2Y0c72ezjOvSvEfAIWsUgpcSDvnC7g9NrjYR6X9bZT92mZZ90TfvXw==} + '@rollup/rollup-linux-arm-musleabihf@4.52.2': + resolution: {integrity: sha512-gKm7Mk9wCv6/rkzwCiUC4KnevYhlf8ztBrDRT9g/u//1fZLapSRc+eDZj2Eu2wpJ+0RzUKgtNijnVIB4ZxyL+w==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.46.4': - resolution: {integrity: sha512-SWuXdnsayCZL4lXoo6jn0yyAj7TTjWE4NwDVt9s7cmu6poMhtiras5c8h6Ih6Y0Zk6Z+8t/mLumvpdSPTWub2Q==} + '@rollup/rollup-linux-arm64-gnu@4.52.2': + resolution: {integrity: sha512-66lA8vnj5mB/rtDNwPgrrKUOtCLVQypkyDa2gMfOefXK6rcZAxKLO9Fy3GkW8VkPnENv9hBkNOFfGLf6rNKGUg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.46.4': - resolution: {integrity: sha512-vDknMDqtMhrrroa5kyX6tuC0aRZZlQ+ipDfbXd2YGz5HeV2t8HOl/FDAd2ynhs7Ki5VooWiiZcCtxiZ4IjqZwQ==} + '@rollup/rollup-linux-arm64-musl@4.52.2': + resolution: {integrity: sha512-s+OPucLNdJHvuZHuIz2WwncJ+SfWHFEmlC5nKMUgAelUeBUnlB4wt7rXWiyG4Zn07uY2Dd+SGyVa9oyLkVGOjA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.46.4': - resolution: {integrity: sha512-mCBkjRZWhvjtl/x+Bd4fQkWZT8canStKDxGrHlBiTnZmJnWygGcvBylzLVCZXka4dco5ymkWhZlLwKCGFF4ivw==} + '@rollup/rollup-linux-loong64-gnu@4.52.2': + resolution: {integrity: sha512-8wTRM3+gVMDLLDdaT6tKmOE3lJyRy9NpJUS/ZRWmLCmOPIJhVyXwjBo+XbrrwtV33Em1/eCTd5TuGJm4+DmYjw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.46.4': - resolution: {integrity: sha512-YMdz2phOTFF+Z66dQfGf0gmeDSi5DJzY5bpZyeg9CPBkV9QDzJ1yFRlmi/j7WWRf3hYIWrOaJj5jsfwgc8GTHQ==} + '@rollup/rollup-linux-ppc64-gnu@4.52.2': + resolution: {integrity: sha512-6yqEfgJ1anIeuP2P/zhtfBlDpXUb80t8DpbYwXQ3bQd95JMvUaqiX+fKqYqUwZXqdJDd8xdilNtsHM2N0cFm6A==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.46.4': - resolution: {integrity: sha512-r0WKLSfFAK8ucG024v2yiLSJMedoWvk8yWqfNICX28NHDGeu3F/wBf8KG6mclghx4FsLePxJr/9N8rIj1PtCnw==} + '@rollup/rollup-linux-riscv64-gnu@4.52.2': + resolution: {integrity: sha512-sshYUiYVSEI2B6dp4jMncwxbrUqRdNApF2c3bhtLAU0qA8Lrri0p0NauOsTWh3yCCCDyBOjESHMExonp7Nzc0w==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.46.4': - resolution: {integrity: sha512-IaizpPP2UQU3MNyPH1u0Xxbm73D+4OupL0bjo4Hm0496e2wg3zuvoAIhubkD1NGy9fXILEExPQy87mweujEatA==} + '@rollup/rollup-linux-riscv64-musl@4.52.2': + resolution: {integrity: sha512-duBLgd+3pqC4MMwBrKkFxaZerUxZcYApQVC5SdbF5/e/589GwVvlRUnyqMFbM8iUSb1BaoX/3fRL7hB9m2Pj8Q==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.46.4': - resolution: {integrity: sha512-aCM29orANR0a8wk896p6UEgIfupReupnmISz6SUwMIwTGaTI8MuKdE0OD2LvEg8ondDyZdMvnaN3bW4nFbATPA==} + '@rollup/rollup-linux-s390x-gnu@4.52.2': + resolution: {integrity: sha512-tzhYJJidDUVGMgVyE+PmxENPHlvvqm1KILjjZhB8/xHYqAGeizh3GBGf9u6WdJpZrz1aCpIIHG0LgJgH9rVjHQ==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.46.4': - resolution: {integrity: sha512-0Xj1vZE3cbr/wda8d/m+UeuSL+TDpuozzdD4QaSzu/xSOMK0Su5RhIkF7KVHFQsobemUNHPLEcYllL7ZTCP/Cg==} + '@rollup/rollup-linux-x64-gnu@4.52.2': + resolution: {integrity: sha512-opH8GSUuVcCSSyHHcl5hELrmnk4waZoVpgn/4FDao9iyE4WpQhyWJ5ryl5M3ocp4qkRuHfyXnGqg8M9oKCEKRA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.46.4': - resolution: {integrity: sha512-kM/orjpolfA5yxsx84kI6bnK47AAZuWxglGKcNmokw2yy9i5eHY5UAjcX45jemTJnfHAWo3/hOoRqEeeTdL5hw==} + '@rollup/rollup-linux-x64-musl@4.52.2': + resolution: {integrity: sha512-LSeBHnGli1pPKVJ79ZVJgeZWWZXkEe/5o8kcn23M8eMKCUANejchJbF/JqzM4RRjOJfNRhKJk8FuqL1GKjF5oQ==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.46.4': - resolution: {integrity: sha512-cNLH4psMEsWKILW0isbpQA2OvjXLbKvnkcJFmqAptPQbtLrobiapBJVj6RoIvg6UXVp5w0wnIfd/Q56cNpF+Ew==} + '@rollup/rollup-openharmony-arm64@4.52.2': + resolution: {integrity: sha512-uPj7MQ6/s+/GOpolavm6BPo+6CbhbKYyZHUDvZ/SmJM7pfDBgdGisFX3bY/CBDMg2ZO4utfhlApkSfZ92yXw7Q==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.52.2': + resolution: {integrity: sha512-Z9MUCrSgIaUeeHAiNkm3cQyst2UhzjPraR3gYYfOjAuZI7tcFRTOD+4cHLPoS/3qinchth+V56vtqz1Tv+6KPA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.46.4': - resolution: {integrity: sha512-OiEa5lRhiANpv4SfwYVgQ3opYWi/QmPDC5ve21m8G9pf6ZO+aX1g2EEF1/IFaM1xPSP7mK0msTRXlPs6mIagkg==} + '@rollup/rollup-win32-ia32-msvc@4.52.2': + resolution: {integrity: sha512-+GnYBmpjldD3XQd+HMejo+0gJGwYIOfFeoBQv32xF/RUIvccUz20/V6Otdv+57NE70D5pa8W/jVGDoGq0oON4A==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.46.4': - resolution: {integrity: sha512-IKL9mewGZ5UuuX4NQlwOmxPyqielvkAPUS2s1cl6yWjjQvyN3h5JTdVFGD5Jr5xMjRC8setOfGQDVgX8V+dkjg==} + '@rollup/rollup-win32-x64-gnu@4.52.2': + resolution: {integrity: sha512-ApXFKluSB6kDQkAqZOKXBjiaqdF1BlKi+/eqnYe9Ee7U2K3pUDKsIyr8EYm/QDHTJIM+4X+lI0gJc3TTRhd+dA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.2': + resolution: {integrity: sha512-ARz+Bs8kY6FtitYM96PqPEVvPXqEZmPZsSkXvyX19YzDqkCaIlhCieLLMI5hxO9SRZ2XtCtm8wxhy0iJ2jxNfw==} cpu: [x64] os: [win32] @@ -4200,8 +4226,8 @@ packages: resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} engines: {node: '>=14.0.0'} - '@smithy/types@4.3.2': - resolution: {integrity: sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw==} + '@smithy/types@4.5.0': + resolution: {integrity: sha512-RkUpIOsVlAwUIZXO1dsz8Zm+N72LClFfsNqf173catVlvRZiwPy0x2u0JLEA4byreOPKDZPGjmPDylMoP8ZJRg==} engines: {node: '>=18.0.0'} '@smithy/util-buffer-from@2.2.0': @@ -4477,8 +4503,8 @@ packages: peerDependencies: '@solana/web3.js': ^1.95.3 - '@solana/spl-token@0.4.13': - resolution: {integrity: sha512-cite/pYWQZZVvLbg5lsodSovbetK/eA24gaR0eeUeMuBAMNrT8XFCwaygKy0N2WSg3gSyjjNpIeAGBAKZaY/1w==} + '@solana/spl-token@0.4.14': + resolution: {integrity: sha512-u09zr96UBpX4U685MnvQsNzlvw9TiY005hk1vJmJr7gMJldoPG1eYU5/wNEyOA5lkMLiR/gOi9SFD4MefOYEsA==} engines: {node: '>=16'} peerDependencies: '@solana/web3.js': ^1.95.5 @@ -4622,11 +4648,11 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} - '@tanstack/query-core@5.85.5': - resolution: {integrity: sha512-KO0WTob4JEApv69iYp1eGvfMSUkgw//IpMnq+//cORBzXf0smyRwPLrUvEe5qtAEGjwZTXrjxg+oJNP/C00t6w==} + '@tanstack/query-core@5.90.2': + resolution: {integrity: sha512-k/TcR3YalnzibscALLwxeiLUub6jN5EDLwKDiO7q5f4ICEoptJ+n9+7vcEFy5/x/i6Q+Lb/tXrsKCggf5uQJXQ==} - '@tanstack/react-query@5.85.5': - resolution: {integrity: sha512-/X4EFNcnPiSs8wM2v+b6DqS5mmGeuJQvxBglmDxl6ZQb5V26ouD2SJYAcC3VjbNwqhY2zjxVD15rDA5nGbMn3A==} + '@tanstack/react-query@5.90.2': + resolution: {integrity: sha512-CLABiR+h5PYfOWr/z+vWFt5VsOA2ekQeRQBFSKlcoW6Ndx/f8rfyVmq4LbgOM4GG2qtxAxjLYLOpCNTYm4uKzw==} peerDependencies: react: ^18 || ^19 @@ -4638,8 +4664,8 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} - '@tybys/wasm-util@0.10.0': - resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==} + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -4713,20 +4739,20 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@18.19.123': - resolution: {integrity: sha512-K7DIaHnh0mzVxreCR9qwgNxp3MH9dltPNIEddW9MYUlcKAzm+3grKNSTe2vCJHI1FaLpvpL5JGJrz1UZDKYvDg==} + '@types/node@18.19.127': + resolution: {integrity: sha512-gSjxjrnKXML/yo0BO099uPixMqfpJU0TKYjpfLU7TrtA2WWDki412Np/RSTPRil1saKBhvVVKzVx/p/6p94nVA==} - '@types/node@20.19.11': - resolution: {integrity: sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==} + '@types/node@20.19.17': + resolution: {integrity: sha512-gfehUI8N1z92kygssiuWvLiwcbOB3IRktR6hTDgJlXMYh5OvkPSRmgfoBUmfZt+vhwJtX7v1Yw4KvvAf7c5QKQ==} - '@types/node@22.17.2': - resolution: {integrity: sha512-gL6z5N9Jm9mhY+U2KXZpteb+09zyffliRkZyZOHODGATyC5B1Jt/7TzuuiLkFsSUMLbS1OLmlj/E+/3KF4Q/4w==} + '@types/node@22.18.6': + resolution: {integrity: sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==} '@types/node@22.7.5': resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} - '@types/node@24.3.0': - resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==} + '@types/node@24.5.2': + resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} '@types/plist@3.0.5': resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} @@ -4737,13 +4763,13 @@ packages: '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/react-dom@19.1.7': - resolution: {integrity: sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==} + '@types/react-dom@19.1.9': + resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} peerDependencies: '@types/react': ^19.0.0 - '@types/react@19.1.10': - resolution: {integrity: sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg==} + '@types/react@19.1.13': + resolution: {integrity: sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==} '@types/responselike@1.0.3': resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} @@ -4784,63 +4810,63 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.40.0': - resolution: {integrity: sha512-w/EboPlBwnmOBtRbiOvzjD+wdiZdgFeo17lkltrtn7X37vagKKWJABvyfsJXTlHe6XBzugmYgd4A4nW+k8Mixw==} + '@typescript-eslint/eslint-plugin@8.44.1': + resolution: {integrity: sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.40.0 + '@typescript-eslint/parser': ^8.44.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.40.0': - resolution: {integrity: sha512-jCNyAuXx8dr5KJMkecGmZ8KI61KBUhkCob+SD+C+I5+Y1FWI2Y3QmY4/cxMCC5WAsZqoEtEETVhUiUMIGCf6Bw==} + '@typescript-eslint/parser@8.44.1': + resolution: {integrity: sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.40.0': - resolution: {integrity: sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==} + '@typescript-eslint/project-service@8.44.1': + resolution: {integrity: sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.40.0': - resolution: {integrity: sha512-y9ObStCcdCiZKzwqsE8CcpyuVMwRouJbbSrNuThDpv16dFAj429IkM6LNb1dZ2m7hK5fHyzNcErZf7CEeKXR4w==} + '@typescript-eslint/scope-manager@8.44.1': + resolution: {integrity: sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.40.0': - resolution: {integrity: sha512-jtMytmUaG9d/9kqSl/W3E3xaWESo4hFDxAIHGVW/WKKtQhesnRIJSAJO6XckluuJ6KDB5woD1EiqknriCtAmcw==} + '@typescript-eslint/tsconfig-utils@8.44.1': + resolution: {integrity: sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.40.0': - resolution: {integrity: sha512-eE60cK4KzAc6ZrzlJnflXdrMqOBaugeukWICO2rB0KNvwdIMaEaYiywwHMzA1qFpTxrLhN9Lp4E/00EgWcD3Ow==} + '@typescript-eslint/type-utils@8.44.1': + resolution: {integrity: sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.40.0': - resolution: {integrity: sha512-ETdbFlgbAmXHyFPwqUIYrfc12ArvpBhEVgGAxVYSwli26dn8Ko+lIo4Su9vI9ykTZdJn+vJprs/0eZU0YMAEQg==} + '@typescript-eslint/types@8.44.1': + resolution: {integrity: sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.40.0': - resolution: {integrity: sha512-k1z9+GJReVVOkc1WfVKs1vBrR5MIKKbdAjDTPvIK3L8De6KbFfPFt6BKpdkdk7rZS2GtC/m6yI5MYX+UsuvVYQ==} + '@typescript-eslint/typescript-estree@8.44.1': + resolution: {integrity: sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.40.0': - resolution: {integrity: sha512-Cgzi2MXSZyAUOY+BFwGs17s7ad/7L+gKt6Y8rAVVWS+7o6wrjeFN4nVfTpbE25MNcxyJ+iYUXflbs2xR9h4UBg==} + '@typescript-eslint/utils@8.44.1': + resolution: {integrity: sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.40.0': - resolution: {integrity: sha512-8CZ47QwalyRjsypfwnbI3hKy5gJDPmrkLjkgMxhi0+DZZ2QNx2naS6/hWoVYUHU7LU2zleF68V9miaVZvhFfTA==} + '@typescript-eslint/visitor-keys@8.44.1': + resolution: {integrity: sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -4941,8 +4967,8 @@ packages: cpu: [x64] os: [win32] - '@upstash/redis@1.35.3': - resolution: {integrity: sha512-hSjv66NOuahW3MisRGlSgoszU2uONAY2l5Qo3Sae8OT3/Tng9K+2/cBRuyPBX8egwEGcNNCF9+r0V6grNnhL+w==} + '@upstash/redis@1.35.4': + resolution: {integrity: sha512-WE1ZnhFyBiIjTDW13GbO6JjkiMVVjw5VsvS8ENmvvJsze/caMQ5paxVD44+U68IUVmkXcbsLSoE+VIYsHtbQEw==} '@vitejs/plugin-react@4.7.0': resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} @@ -4979,18 +5005,18 @@ packages: '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@wagmi/connectors@5.9.4': - resolution: {integrity: sha512-k/GSdYS6nuL0zLq5H7XasPmKr3Gnvplq+yQhTfRBu/o5Bh+B3aH3Jfq1lUh+t3z5kQcyKJIXw/bZIZ7lVS7UhA==} + '@wagmi/connectors@5.11.1': + resolution: {integrity: sha512-2jbx6z8rk/srQdbnKF2viCc3ke02HSMQU5EZS90jWoJ1t4+Fn3+bhphgVeJ1LnVFWsuEBSuIcY63iic4emwGfg==} peerDependencies: - '@wagmi/core': 2.19.0 + '@wagmi/core': 2.21.1 typescript: '>=5.0.4' viem: 2.x peerDependenciesMeta: typescript: optional: true - '@wagmi/core@2.19.0': - resolution: {integrity: sha512-lI57q6refAtNU6xnk/oyOpbEtEiwQ6g4rR+C9FEx8Gn2hZlfoyyksndrl6hIKlMBK+UkkKso3VwR5DI65j/5XQ==} + '@wagmi/core@2.21.1': + resolution: {integrity: sha512-uG0Cujm24acrFYqbi1RGw9MRMLTGVKvyv5OAJT+2pkcasM9PP8eJCzhlvUxK9IYVXXnbaAT8JX/rXEurOSM6mg==} peerDependencies: '@tanstack/query-core': '>=5.0.0' typescript: '>=5.0.4' @@ -5118,11 +5144,22 @@ packages: zod: optional: true - abitype@1.0.9: - resolution: {integrity: sha512-oN0S++TQmlwWuB+rkA6aiEefLv3SP+2l/tC5mux/TLj6qdA6rF15Vbpex4fHovLsMkwLwTIRj8/Q8vXCS3GfOg==} + abitype@1.1.0: + resolution: {integrity: sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==} peerDependencies: typescript: '>=5.0.4' - zod: ^3 >=3.22.0 + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.1.1: + resolution: {integrity: sha512-Loe5/6tAgsBukY95eGaPSDmQHIjRZYQq8PB1MpsNccDIK8WiV+Uw6WzaIXipvaxTEL2yEB0OpEaQv3gs8pkS9Q==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3.22.0 || ^4.0.0 peerDependenciesMeta: typescript: optional: true @@ -5185,8 +5222,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.0: - resolution: {integrity: sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} ansi-styles@4.3.0: @@ -5197,8 +5234,8 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} any-promise@1.3.0: @@ -5336,8 +5373,8 @@ packages: peerDependencies: axios: 0.x || 1.x - axios@1.11.0: - resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==} + axios@1.12.2: + resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -5373,6 +5410,10 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.8.6: + resolution: {integrity: sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==} + hasBin: true + big.js@6.2.2: resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} @@ -5424,8 +5465,8 @@ packages: borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} - bowser@2.12.0: - resolution: {integrity: sha512-HcOcTudTeEWgbHh0Y1Tyb6fdeR71m4b/QACf0D4KswGTsNeIJQmg38mRENZPAYPZvGFN3fk3604XbQEPdxXdKg==} + bowser@2.12.1: + resolution: {integrity: sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==} brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -5440,8 +5481,8 @@ packages: brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - browserslist@4.25.3: - resolution: {integrity: sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ==} + browserslist@4.26.2: + resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -5543,23 +5584,23 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001735: - resolution: {integrity: sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w==} + caniuse-lite@1.0.30001745: + resolution: {integrity: sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==} canonicalize@2.1.0: resolution: {integrity: sha512-F705O3xrsUtgt98j7leetNhTWPe+5S72rlL5O4jA1pKqBVQ/dT1O1D6PFxmSXvc0SUOinWS57DKx0I3CHrXJHQ==} hasBin: true - chai@5.3.1: - resolution: {integrity: sha512-48af6xm9gQK8rhIcOxWwdGzIervm8BVTin+yRp9HEvU20BtVZ2lBywlIJBzwaDtvo0FvjeL7QdCADoUoqIbV3A==} + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.6.0: - resolution: {integrity: sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} charenc@0.0.2: @@ -5588,8 +5629,8 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - cipher-base@1.0.6: - resolution: {integrity: sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==} + cipher-base@1.0.7: + resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} engines: {node: '>= 0.10'} classnames@2.5.1: @@ -5655,10 +5696,6 @@ packages: color@3.2.1: resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - colorspace@1.1.4: resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} @@ -5673,8 +5710,8 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} - commander@14.0.0: - resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} + commander@14.0.1: + resolution: {integrity: sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==} engines: {node: '>=20'} commander@2.20.3: @@ -5712,8 +5749,8 @@ packages: engines: {node: ^14.13.0 || >=16.0.0} hasBin: true - concurrently@9.2.0: - resolution: {integrity: sha512-IsB/fiXTupmagMW4MNp2lx2cdSN2FfZq78vF90LBB+zZHArbIQZjQtzXCiXnvTxCZSvXanTqFLWBjw2UkLx1SQ==} + concurrently@9.2.1: + resolution: {integrity: sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==} engines: {node: '>=18'} hasBin: true @@ -5895,8 +5932,8 @@ packages: supports-color: optional: true - debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -5904,8 +5941,8 @@ packages: supports-color: optional: true - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -5984,8 +6021,8 @@ packages: detect-browser@5.3.0: resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} - detect-libc@2.0.4: - resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + detect-libc@2.1.1: + resolution: {integrity: sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==} engines: {node: '>=8'} detect-node-es@1.1.0: @@ -6091,15 +6128,15 @@ packages: electron-publish@26.0.11: resolution: {integrity: sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A==} - electron-to-chromium@1.5.207: - resolution: {integrity: sha512-mryFrrL/GXDTmAtIVMVf+eIXM09BBPlO5IQ7lUyKmK8d+A4VpRGG+M3ofoVef6qyF8s60rJei8ymlJxjUA8Faw==} + electron-to-chromium@1.5.223: + resolution: {integrity: sha512-qKm55ic6nbEmagFlTFczML33rF90aU+WtrJ9MdTCThrcvDNdUHN4p6QfVN78U06ZmguqXIyMPyYhw2TrbDUwPQ==} electron-winstaller@5.4.0: resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} engines: {node: '>=8.0.0'} - electron@37.3.1: - resolution: {integrity: sha512-7DhktRLqhe6OJh/Bo75bTI0puUYEmIwSzMinocgO63mx3MVjtIn2tYMzLmAleNIlud2htkjpsMG2zT4PiTCloA==} + electron@37.5.1: + resolution: {integrity: sha512-RqN3dl6I5yhmynkUc3pUzM6qFCvANau3VGRX9xQEh7FYdwmkqVxKXYM5enrE9LW7j7PzHomQQn6+J2xaF7BHsQ==} engines: {node: '>= 12.20.55'} hasBin: true @@ -6154,8 +6191,8 @@ packages: err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} es-abstract@1.24.0: resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} @@ -6209,8 +6246,8 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.25.9: - resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} + esbuild@0.25.10: + resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} engines: {node: '>=18'} hasBin: true @@ -6356,8 +6393,8 @@ packages: deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true - eslint@9.33.0: - resolution: {integrity: sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==} + eslint@9.36.0: + resolution: {integrity: sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -6435,9 +6472,9 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - eventsource-parser@3.0.5: - resolution: {integrity: sha512-bSRG85ZrMdmWtm7qkF9He9TNRzc/Bm99gEJMaQoHJ9E6Kv9QBbsldh2oMj7iXmYNEAVvNgvv5vPorG6W+XtBhQ==} - engines: {node: '>=20.0.0'} + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} eventsource@3.0.7: resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} @@ -6518,8 +6555,8 @@ packages: fast-stable-stringify@1.0.0: resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} - fast-uri@3.0.6: - resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} fastestsmallesttextencoderdecoder@1.0.22: resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} @@ -6649,8 +6686,8 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-extra@11.3.1: - resolution: {integrity: sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==} + fs-extra@11.3.2: + resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} engines: {node: '>=14.14'} fs-extra@7.0.1: @@ -6820,9 +6857,9 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hash-base@3.1.0: - resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} - engines: {node: '>=4'} + hash-base@3.1.2: + resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} + engines: {node: '>= 0.8'} hash.js@1.1.7: resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} @@ -6834,8 +6871,8 @@ packages: hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} - hono@4.9.2: - resolution: {integrity: sha512-UG2jXGS/gkLH42l/1uROnwXpkjvvxkl3kpopL3LBo27NuaDPI6xHNfuUSilIHcrBkPfl4y0z6y2ByI455TjNRw==} + hono@4.9.8: + resolution: {integrity: sha512-JW8Bb4RFWD9iOKxg5PbUarBYGM99IcxFl2FPBo2gSJO11jjUDqlP1Bmfyqt8Z/dGhIQ63PMA9LdcLefXyIasyg==} engines: {node: '>=16.9.0'} hosted-git-info@4.1.0: @@ -6900,6 +6937,10 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.0: + resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} + engines: {node: '>=0.10.0'} + idb-keyval@6.2.1: resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} @@ -6965,8 +7006,8 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} is-async-function@2.1.1: resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} @@ -7049,8 +7090,8 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - is-network-error@1.1.0: - resolution: {integrity: sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==} + is-network-error@1.3.0: + resolution: {integrity: sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==} engines: {node: '>=16'} is-number-object@1.1.1: @@ -7129,8 +7170,8 @@ packages: resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} engines: {node: '>= 8.0.0'} - isbinaryfile@5.0.4: - resolution: {integrity: sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==} + isbinaryfile@5.0.6: + resolution: {integrity: sha512-I+NmIfBHUl+r2wcDd6JwE9yWje/PIVY/R5/CmV8dXLZd5K+L9X2klAOwfAHNnondLXkbHyTAleQAWonpTJBTtw==} engines: {node: '>= 18.0.0'} isexe@2.0.0: @@ -7178,8 +7219,8 @@ packages: jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} - jose@6.0.12: - resolution: {integrity: sha512-T8xypXs8CpmiIi78k0E+Lk7T2zlK4zDyg+o1CZ4AkOHgDg98ogdP2BeZ61lTFKFyoEwJ9RgAgN+SdM3iPgNonQ==} + jose@6.1.0: + resolution: {integrity: sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==} joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} @@ -7211,11 +7252,6 @@ packages: canvas: optional: true - jsesc@3.0.2: - resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} - engines: {node: '>=6'} - hasBin: true - jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -7278,8 +7314,8 @@ packages: kuler@2.0.0: resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - langsmith@0.3.62: - resolution: {integrity: sha512-ApoGLs28cJCxL91l1PDDkjsA4oLrbeNlE1pyTvyopqXq9bNJrP8JPUNWZm/tpU0DzZpvZFctRzru4gNAr/bkxg==} + langsmith@0.3.69: + resolution: {integrity: sha512-YKzu92YAP2o+d+1VmR38xqFX0RIRLKYj1IqdflVEY83X0FoiVlrWO3xDLXgnu7vhZ2N2M6jx8VO9fVF8yy9gHA==} peerDependencies: '@opentelemetry/api': '*' '@opentelemetry/exporter-trace-otlp-proto': '*' @@ -7312,8 +7348,8 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - libphonenumber-js@1.12.13: - resolution: {integrity: sha512-QZXnR/OGiDcBjF4hGk0wwVrPcZvbSSyzlvkjXv5LFfktj7O2VZDrt4Xs8SgR/vOFco+qk1i8J43ikMXZoTrtPw==} + libphonenumber-js@1.12.22: + resolution: {integrity: sha512-nzdkDyqlcLV754o1RrOJxh8kycG+63odJVUqnK4dxhw7buNkdTqJc/a/CE0h599dTJgFbzvr6GEOemFBSBryAA==} lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} @@ -7350,9 +7386,6 @@ packages: lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -7374,8 +7407,8 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - loupe@3.2.0: - resolution: {integrity: sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==} + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -7401,8 +7434,8 @@ packages: magic-bytes.js@1.12.1: resolution: {integrity: sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==} - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} make-fetch-happen@10.2.1: resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} @@ -7580,12 +7613,15 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.7.4: - resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} + mlly@1.8.0: + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -7624,8 +7660,8 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} - next@15.5.0: - resolution: {integrity: sha512-N1lp9Hatw3a9XLt0307lGB4uTKsXDhyOKQo7uYMzX4i0nF/c27grcGXkLdb7VcT8QPYLBa8ouIyEoUQJ2OyeNQ==} + next@15.5.4: + resolution: {integrity: sha512-xH4Yjhb82sFYQfY3vbkJfgSDgXvBB6a8xPs9i35k6oZJRoQRihZH+4s9Yo2qsWpzBmZ3lPXaJ2KPXLfkvW4LnA==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -7648,8 +7684,8 @@ packages: no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - node-abi@3.75.0: - resolution: {integrity: sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==} + node-abi@3.77.0: + resolution: {integrity: sha512-DSmt0OEcLoK4i3NuscSbGjOf3bqiDEutejqENSplMSFA/gmB8mkED9G4pKWnPl7MDU4rSHebKPHeitpDfyH0cQ==} engines: {node: '>=10'} node-addon-api@1.7.2: @@ -7693,11 +7729,11 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-mock-http@1.0.2: - resolution: {integrity: sha512-zWaamgDUdo9SSLw47we78+zYw/bDr5gH8pH7oRRs8V3KmBtu8GLgGIbV2p/gRPd3LWpEOpjQj7X1FOU3VFMJ8g==} + node-mock-http@1.0.3: + resolution: {integrity: sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==} - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + node-releases@2.0.21: + resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} nopt@6.0.0: resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} @@ -7719,8 +7755,8 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nwsapi@2.2.21: - resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} + nwsapi@2.2.22: + resolution: {integrity: sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==} obj-multiplex@1.0.0: resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} @@ -7793,8 +7829,8 @@ packages: zod: optional: true - openai@5.13.1: - resolution: {integrity: sha512-Jty97Apw40znKSlXZL2YDap1U2eN9NfXbqm/Rj1rExeOLEnhwezpKQ+v43kIqojavUgm30SR3iuvGlNEBR+AFg==} + openai@5.23.0: + resolution: {integrity: sha512-Cfq155NHzI7VWR67LUNJMIgPZy2oSh7Fld/OKhxq648BiUjELAvcge7g30xJ6vAfwwXf6TVK0KKuN+3nmIJG/A==} hasBin: true peerDependencies: ws: ^8.18.0 @@ -7805,6 +7841,12 @@ packages: zod: optional: true + openapi-fetch@0.13.8: + resolution: {integrity: sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ==} + + openapi-typescript-helpers@0.0.15: + resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} + opensea-js@7.2.1: resolution: {integrity: sha512-vy7sz2lRMCANrQs9rhNdUsmFSJBjPq1we3/Aib9/sTNudg9830ZvN7XD5if2LBq71L+85tUsxobSNRLBwoEAAg==} engines: {node: '>=20.0.0'} @@ -7853,8 +7895,16 @@ packages: typescript: optional: true - ox@0.8.7: - resolution: {integrity: sha512-W1f0FiMf9NZqtHPEDEAEkyzZDwbIKfmH2qmQx8NNiQ/9JhxrSblmtLJsSfTtQG5YKowLOnBlLVguCyxm/7ztxw==} + ox@0.9.6: + resolution: {integrity: sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.9.7: + resolution: {integrity: sha512-KX9Lvv0Rd+SKZXcT6Y85cuYbkmrQbK8Bz26k+s3X4EiT5bSU/hTDNSK/ApBeorJeIaOZbxEmJD2hHW0q1vIDEA==} peerDependencies: typescript: '>=5.4.0' peerDependenciesMeta: @@ -7958,9 +8008,8 @@ packages: path-to-regexp@0.1.12: resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} - path-to-regexp@8.2.0: - resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} - engines: {node: '>=16'} + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -8042,6 +8091,26 @@ packages: resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==} engines: {node: '>=12.0.0'} + porto@0.2.19: + resolution: {integrity: sha512-q1vEJgdtlEOf6byWgD31GHiMwpfLuxFSfx9f7Sw4RGdvpQs2ANBGfnzzardADZegr87ZXsebSp+3vaaznEUzPQ==} + hasBin: true + peerDependencies: + '@tanstack/react-query': '>=5.59.0' + '@wagmi/core': '>=2.16.3' + react: '>=18' + typescript: '>=5.4.0' + viem: '>=2.37.0' + wagmi: '>=2.0.0' + peerDependenciesMeta: + '@tanstack/react-query': + optional: true + react: + optional: true + typescript: + optional: true + wagmi: + optional: true + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -8052,8 +8121,8 @@ packages: peerDependencies: postcss: ^8.0.0 - postcss-js@4.0.1: - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 @@ -8117,8 +8186,8 @@ packages: preact@10.24.2: resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} - preact@10.27.1: - resolution: {integrity: sha512-V79raXEWch/rbqoNc7nT9E4ep7lu+mI3+sBmfRD4i1M73R3WLYcCtdI0ibxGVf4eQL8ZIz2nFacqEC+rmnOORQ==} + preact@10.27.2: + resolution: {integrity: sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -8246,9 +8315,9 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - raw-body@3.0.0: - resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} - engines: {node: '>= 0.8'} + raw-body@3.0.1: + resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} + engines: {node: '>= 0.10'} react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} @@ -8353,8 +8422,8 @@ packages: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} - regenerate-unicode-properties@10.2.0: - resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} + regenerate-unicode-properties@10.2.2: + resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} engines: {node: '>=4'} regenerate@1.4.2: @@ -8364,19 +8433,19 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} - regexpu-core@6.2.0: - resolution: {integrity: sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==} + regexpu-core@6.4.0: + resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} engines: {node: '>=4'} regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.12.0: - resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} + regjsparser@0.13.0: + resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} hasBin: true - remeda@2.30.0: - resolution: {integrity: sha512-TcRpI1ecqnMer3jHhFtMerGvHFCDlCHljUp0/9A4HxHOh5bSY3kP1l8nQDFMnWYJKl3MSarDNY1tb0Bs/bCmvw==} + remeda@2.32.0: + resolution: {integrity: sha512-BZx9DsT4FAgXDTOdgJIc5eY6ECIXMwtlSPQoPglF20ycSWigttDDe88AozEsPPT4OWk5NujroGSBC1phw5uU+w==} require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} @@ -8448,15 +8517,16 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - ripemd160@2.0.2: - resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + ripemd160@2.0.3: + resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} + engines: {node: '>= 0.8'} roarr@2.15.4: resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} engines: {node: '>=8.0'} - rollup@4.46.4: - resolution: {integrity: sha512-YbxoxvoqNg9zAmw4+vzh1FkGAiZRK+LhnSrbSrSXMdZYsRPDWoshcSd/pldKRO6lWzv/e9TiJAVQyirYIeSIPQ==} + rollup@4.52.2: + resolution: {integrity: sha512-I25/2QgoROE1vYV+NQ1En9T9UFB9Cmfm2CJ83zZOlaDpvz29wGQSZXWKw7MiNXau7wYgB/T9fVIdIuEQ+KbiiA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -8464,8 +8534,8 @@ packages: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} - rpc-websockets@9.1.3: - resolution: {integrity: sha512-I+kNjW0udB4Fetr3vvtRuYZJS0PcSPyyvBcH5sDdoV8DFs5E4W2pTr7aiMlKfPxANTClP9RlqCPolj9dd5MsEA==} + rpc-websockets@9.2.0: + resolution: {integrity: sha512-DS/XHdPxplQTtNRKiBCRWGBJfjOk56W7fyFUpiYi9fSTWTzoEMbUkn3J4gB0IMniIEVeAGR1/rzFQogzD5MxvQ==} rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} @@ -8583,8 +8653,8 @@ packages: engines: {node: '>= 0.10'} hasBin: true - sharp@0.34.3: - resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} + sharp@0.34.4: + resolution: {integrity: sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@2.0.0: @@ -8625,8 +8695,8 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} simple-update-notifier@2.0.0: resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} @@ -8799,8 +8869,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} strip-bom@3.0.0: @@ -8868,8 +8938,8 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - svix@1.74.1: - resolution: {integrity: sha512-99J8jSsk0viwkoAENVy/zpVoZxwn3kBdUvvpFaWiKjCkkTcqNZdoBqMmariDFceL4Q41ntWfUYxaWD37IAk9Kg==} + svix@1.76.1: + resolution: {integrity: sha512-CRuDWBTgYfDnBLRaZdKp9VuoPcNUq9An14c/k+4YJ15Qc5Grvf66vp0jvTltd4t7OIRj+8lM1DAgvSgvf7hdLw==} symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -8878,9 +8948,15 @@ packages: resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} engines: {node: ^14.18.0 || >=16.0.0} + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + tailwind-merge@2.6.0: resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} + tailwind-merge@3.3.1: + resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} + tailwindcss@3.4.17: resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} engines: {node: '>=14.0.0'} @@ -8925,8 +9001,8 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} tinypool@1.1.1: @@ -8937,8 +9013,8 @@ packages: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} - tinyspy@4.0.3: - resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} engines: {node: '>=14.0.0'} tldts-core@6.1.86: @@ -8955,8 +9031,8 @@ packages: resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} engines: {node: '>=14.14'} - to-buffer@1.2.1: - resolution: {integrity: sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==} + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} engines: {node: '>= 0.4'} to-regex-range@5.0.1: @@ -9069,50 +9145,50 @@ packages: typescript: optional: true - tsx@4.20.4: - resolution: {integrity: sha512-yyxBKfORQ7LuRt/BQKBXrpcq59ZvSW0XxwfjAt3w2/8PmdxaFzijtMhTawprSHhpzeM5BgU2hXHG3lklIERZXg==} + tsx@4.20.5: + resolution: {integrity: sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==} engines: {node: '>=18.0.0'} hasBin: true - turbo-darwin-64@2.5.6: - resolution: {integrity: sha512-3C1xEdo4aFwMJAPvtlPqz1Sw/+cddWIOmsalHFMrsqqydcptwBfu26WW2cDm3u93bUzMbBJ8k3zNKFqxJ9ei2A==} + turbo-darwin-64@2.5.8: + resolution: {integrity: sha512-Dh5bCACiHO8rUXZLpKw+m3FiHtAp2CkanSyJre+SInEvEr5kIxjGvCK/8MFX8SFRjQuhjtvpIvYYZJB4AGCxNQ==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.5.6: - resolution: {integrity: sha512-LyiG+rD7JhMfYwLqB6k3LZQtYn8CQQUePbpA8mF/hMLPAekXdJo1g0bUPw8RZLwQXUIU/3BU7tXENvhSGz5DPA==} + turbo-darwin-arm64@2.5.8: + resolution: {integrity: sha512-f1H/tQC9px7+hmXn6Kx/w8Jd/FneIUnvLlcI/7RGHunxfOkKJKvsoiNzySkoHQ8uq1pJnhJ0xNGTlYM48ZaJOQ==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.5.6: - resolution: {integrity: sha512-GOcUTT0xiT/pSnHL4YD6Yr3HreUhU8pUcGqcI2ksIF9b2/r/kRHwGFcsHgpG3+vtZF/kwsP0MV8FTlTObxsYIA==} + turbo-linux-64@2.5.8: + resolution: {integrity: sha512-hMyvc7w7yadBlZBGl/bnR6O+dJTx3XkTeyTTH4zEjERO6ChEs0SrN8jTFj1lueNXKIHh1SnALmy6VctKMGnWfw==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.5.6: - resolution: {integrity: sha512-10Tm15bruJEA3m0V7iZcnQBpObGBcOgUcO+sY7/2vk1bweW34LMhkWi8svjV9iDF68+KJDThnYDlYE/bc7/zzQ==} + turbo-linux-arm64@2.5.8: + resolution: {integrity: sha512-LQELGa7bAqV2f+3rTMRPnj5G/OHAe2U+0N9BwsZvfMvHSUbsQ3bBMWdSQaYNicok7wOZcHjz2TkESn1hYK6xIQ==} cpu: [arm64] os: [linux] - turbo-windows-64@2.5.6: - resolution: {integrity: sha512-FyRsVpgaj76It0ludwZsNN40ytHN+17E4PFJyeliBEbxrGTc5BexlXVpufB7XlAaoaZVxbS6KT8RofLfDRyEPg==} + turbo-windows-64@2.5.8: + resolution: {integrity: sha512-3YdcaW34TrN1AWwqgYL9gUqmZsMT4T7g8Y5Azz+uwwEJW+4sgcJkIi9pYFyU4ZBSjBvkfuPZkGgfStir5BBDJQ==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.5.6: - resolution: {integrity: sha512-j/tWu8cMeQ7HPpKri6jvKtyXg9K1gRyhdK4tKrrchH8GNHscPX/F71zax58yYtLRWTiK04zNzPcUJuoS0+v/+Q==} + turbo-windows-arm64@2.5.8: + resolution: {integrity: sha512-eFC5XzLmgXJfnAK3UMTmVECCwuBcORrWdewoiXBnUm934DY6QN8YowC/srhNnROMpaKaqNeRpoB5FxCww3eteQ==} cpu: [arm64] os: [win32] - turbo@2.5.6: - resolution: {integrity: sha512-gxToHmi9oTBNB05UjUsrWf0OyN5ZXtD0apOarC1KIx232Vp3WimRNy3810QzeNSgyD5rsaIDXlxlbnOzlouo+w==} + turbo@2.5.8: + resolution: {integrity: sha512-5c9Fdsr9qfpT3hA0EyYSFRZj1dVVsb6KIWubA9JBYZ/9ZEAijgUEae0BBR/Xl/wekt4w65/lYLTFaP3JmwSO8w==} hasBin: true tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} - twitter-api-v2@1.25.0: - resolution: {integrity: sha512-g3JDd5jwJD+gkEe2Qn3GI5GpasYJjFEauTw70kqiBGu+ectWUgtEKtIaZUGKB50+ApyNhl6v871YCS6un6YEJw==} + twitter-api-v2@1.27.0: + resolution: {integrity: sha512-hbIFwzg0NeOcFOdmJqtKMCXjLjc0INff/7NwhnZ2zpnw65oku8i+0eMxo5M0iTc1hs+inD/IpDw3S0Xh2c45QQ==} type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -9188,11 +9264,11 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.10.0: - resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} + undici-types@7.12.0: + resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} - undici-types@7.14.0: - resolution: {integrity: sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} unicode-canonical-property-names-ecmascript@2.0.1: resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} @@ -9202,12 +9278,12 @@ packages: resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} engines: {node: '>=4'} - unicode-match-property-value-ecmascript@2.2.0: - resolution: {integrity: sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==} + unicode-match-property-value-ecmascript@2.2.1: + resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} engines: {node: '>=4'} - unicode-property-aliases-ecmascript@2.1.0: - resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + unicode-property-aliases-ecmascript@2.2.0: + resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} engines: {node: '>=4'} unique-filename@2.0.1: @@ -9233,8 +9309,8 @@ packages: unrs-resolver@1.11.1: resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} - unstorage@1.16.1: - resolution: {integrity: sha512-gdpZ3guLDhz+zWIlYP1UwQ259tG5T5vYRzDaHMkQ1bBY1SQPutvZnrRjTFaWUUpseErJIgAZS51h6NOcZVZiqQ==} + unstorage@1.17.1: + resolution: {integrity: sha512-KKGwRTT0iVBCErKemkJCLs7JdxNVfqTPc/85ae1XES0+bsHbc/sFBfVi5kJp156cc51BHinIH2l3k0EZ24vOBQ==} peerDependencies: '@azure/app-configuration': ^1.8.0 '@azure/cosmos': ^4.2.0 @@ -9248,6 +9324,7 @@ packages: '@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.0.1 aws4fetch: ^1.0.20 db0: '>=0.2.1' @@ -9279,6 +9356,8 @@ packages: optional: true '@vercel/blob': optional: true + '@vercel/functions': + optional: true '@vercel/kv': optional: true aws4fetch: @@ -9339,6 +9418,12 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + usehooks-ts@3.1.1: + resolution: {integrity: sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA==} + engines: {node: '>=16.15.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc + utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} engines: {node: '>=6.14.2'} @@ -9399,8 +9484,8 @@ packages: typescript: optional: true - viem@2.34.0: - resolution: {integrity: sha512-HJZG9Wt0DLX042MG0PK17tpataxtdAEhpta9/Q44FqKwy3xZMI5Lx4jF+zZPuXFuYjZ68R0PXqRwlswHs6r4gA==} + viem@2.37.8: + resolution: {integrity: sha512-mL+5yvCQbRIR6QvngDQMfEiZTfNWfd+/QL5yFaOoYbpH3b1Q2ddwF7YG2eI2AcYSh9LE1gtUkbzZLFUAVyj4oQ==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -9420,8 +9505,8 @@ packages: vite: optional: true - vite@6.3.5: - resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} + vite@6.3.6: + resolution: {integrity: sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -9460,8 +9545,8 @@ packages: yaml: optional: true - vite@7.1.3: - resolution: {integrity: sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==} + vite@7.1.7: + resolution: {integrity: sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -9532,8 +9617,8 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - wagmi@2.16.4: - resolution: {integrity: sha512-HthfF/6g7qPnCttl9tLkKoJdWKqMH3Isx4DJ+mkn//Ubom0eKnXH2hr2SMVGTqNQUpsi1knYLUWDGJYkT4hoog==} + wagmi@2.17.4: + resolution: {integrity: sha512-AJpTQ5O7JFv2LDaRuMiCKxZEVBeDprh9oagA0dLSp/iAEsbd5VwmMy3rn4lCO3pl9umJ+afEkuRIq+5dx02jzg==} peerDependencies: '@tanstack/react-query': '>=5.0.0' react: '>=18' @@ -9719,8 +9804,8 @@ packages: x402@0.4.3: resolution: {integrity: sha512-GbIgX2EZYAOZX1ZrEYIVXtjDKLtNuwp7lUlM3dCJAF5TqELP+bDrLy3UsypzNcJoHPVvNa+jB4BPZ83/W2nZDA==} - x402@0.5.3: - resolution: {integrity: sha512-2cML/exWWnusJjmrzanILGAtSoatVR5U8w4Xf6RNpqpOO1xCakyEDgoSCKWAu+KAYoO27xmCXmbIy/ao2sBCMw==} + x402@0.6.1: + resolution: {integrity: sha512-9UmeCSsYzFGav5FdVP70VplKlR3V90P0DZ9fPSrlLVp0ifUVi1S9TztvegkmIHE9xTGZ1GWNi+bkne6N0Ea58w==} x402@file:../../typescript/packages/x402: resolution: {directory: ../../typescript/packages/x402, type: directory} @@ -9796,6 +9881,9 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.1.11: + resolution: {integrity: sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==} + zustand@5.0.0: resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} engines: {node: '>=12.20.0'} @@ -9854,29 +9942,24 @@ snapshots: 7zip-bin@5.2.0: {} - '@across-protocol/app-sdk@0.2.3(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@across-protocol/app-sdk@0.2.3(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@adraffy/ens-normalize@1.10.1': {} - '@adraffy/ens-normalize@1.11.0': {} + '@adraffy/ens-normalize@1.11.1': {} '@alloc/quick-lru@5.2.0': {} '@alloralabs/allora-sdk@0.1.1': dependencies: - '@types/node': 22.17.2 + '@types/node': 22.18.6 typescript: 5.9.2 - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 - '@anthropic-ai/sdk@0.39.0(encoding@0.1.13)': dependencies: - '@types/node': 18.19.123 + '@types/node': 18.19.127 '@types/node-fetch': 2.6.13 abort-controller: 3.0.0 agentkeepalive: 4.6.0 @@ -9891,7 +9974,7 @@ snapshots: '@asamuzakjp/css-color@3.2.0': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-color-parser': 3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 lru-cache: 10.4.3 @@ -9899,18 +9982,18 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.862.0 + '@aws-sdk/types': 3.893.0 tslib: 2.8.1 '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.862.0 + '@aws-sdk/types': 3.893.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/types@3.862.0': + '@aws-sdk/types@3.893.0': dependencies: - '@smithy/types': 4.3.2 + '@smithy/types': 4.5.0 tslib: 2.8.1 '@babel/code-frame@7.27.1': @@ -9919,22 +10002,22 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.0': {} + '@babel/compat-data@7.28.4': {} - '@babel/core@7.28.3': + '@babel/core@7.28.4': dependencies: - '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.3 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) - '@babel/helpers': 7.28.3 - '@babel/parser': 7.28.3 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.1 + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -9943,50 +10026,50 @@ snapshots: '@babel/generator@7.28.3': dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.28.0 + '@babel/compat-data': 7.28.4 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.25.3 + browserslist: 4.26.2 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.3)': + '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.3)': + '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 - regexpu-core: 6.2.0 + regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.3)': + '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - debug: 4.4.1 + debug: 4.4.3 lodash.debounce: 4.0.8 resolve: 1.22.10 transitivePeerDependencies: @@ -9996,55 +10079,55 @@ snapshots: '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.3)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.3)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-wrap-function': 7.28.3 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.3)': + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color @@ -10057,605 +10140,605 @@ snapshots: '@babel/helper-wrap-function@7.28.3': dependencies: '@babel/template': 7.27.2 - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/helpers@7.28.3': + '@babel/helpers@7.28.4': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 - '@babel/parser@7.28.3': + '@babel/parser@7.28.4': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.4) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.3)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.3)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 - '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.3)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.3) - '@babel/traverse': 7.28.3 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.4) + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.3) + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-block-scoping@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-block-scoping@7.28.4(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.3)': + '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.28.3(@babel/core@7.28.3)': + '@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-globals': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) - '@babel/traverse': 7.28.3 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/template': 7.27.2 - '@babel/plugin-transform-destructuring@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-destructuring@7.28.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-object-rest-spread@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.3) - '@babel/traverse': 7.28.3 + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.4) + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.3)': + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) - '@babel/types': 7.28.2 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regenerator@7.28.3(@babel/core@7.28.3)': + '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/preset-env@7.28.3(@babel/core@7.28.3)': + '@babel/preset-env@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/compat-data': 7.28.0 - '@babel/core': 7.28.3 + '@babel/compat-data': 7.28.4 + '@babel/core': 7.28.4 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.3) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.3) - '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.3) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-block-scoping': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.3) - '@babel/plugin-transform-classes': 7.28.3(@babel/core@7.28.3) - '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-object-rest-spread': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.3) - '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-regenerator': 7.28.3(@babel/core@7.28.3) - '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.3) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.3) - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.3) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.3) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.3) + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.4) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.4) + '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.4) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-block-scoping': 7.28.4(@babel/core@7.28.4) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.4) + '@babel/plugin-transform-classes': 7.28.4(@babel/core@7.28.4) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.4) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.4) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.28.4) + '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.4) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.4) + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.4) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.4) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.4) core-js-compat: 3.45.1 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.3)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 esutils: 2.0.3 - '@babel/preset-react@7.27.1(@babel/core@7.28.3)': + '@babel/preset-react@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.4) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.27.1(@babel/core@7.28.3)': + '@babel/preset-typescript@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.4) transitivePeerDependencies: - supports-color - '@babel/runtime@7.28.3': {} + '@babel/runtime@7.28.4': {} '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 - '@babel/traverse@7.28.3': + '@babel/traverse@7.28.4': dependencies: '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.3 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.3 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - debug: 4.4.1 + '@babel/types': 7.28.4 + debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.28.2': + '@babel/types@7.28.4': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@base-org/account@1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@base-org/account@1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/hashes': 1.4.0 clsx: 1.2.1 @@ -10663,8 +10746,28 @@ snapshots: idb-keyval: 6.2.1 ox: 0.6.9(typescript@5.9.2)(zod@3.25.76) preact: 10.24.2 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@base-org/account@1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.9.2)(zod@4.1.11) + preact: 10.24.2 + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -10675,7 +10778,7 @@ snapshots: - utf-8-validate - zod - '@base-org/account@1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@base-org/account@1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/hashes': 1.4.0 clsx: 1.2.1 @@ -10683,8 +10786,8 @@ snapshots: idb-keyval: 6.2.1 ox: 0.6.9(typescript@5.9.2)(zod@3.25.76) preact: 10.24.2 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -10697,10 +10800,10 @@ snapshots: '@cfworker/json-schema@4.1.1': {} - '@coinbase/agentkit-langchain@0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': + '@coinbase/agentkit-langchain@0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': dependencies: '@coinbase/agentkit': 0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) zod: 3.25.76 transitivePeerDependencies: - '@opentelemetry/api' @@ -10710,12 +10813,12 @@ snapshots: '@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/app-sdk': 0.2.3(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@across-protocol/app-sdk': 0.2.3(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) '@alloralabs/allora-sdk': 0.1.1 '@coinbase/coinbase-sdk': 0.20.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@jup-ag/api': 6.0.44 - '@privy-io/server-auth': 1.31.1(bufferutil@4.0.9)(encoding@0.1.13)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@privy-io/server-auth': 1.32.5(bufferutil@4.0.9)(encoding@0.1.13)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@solana/spl-token': 0.4.14(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) bs58: 4.0.1 canonicalize: 2.1.0 @@ -10724,8 +10827,8 @@ snapshots: md5: 2.3.0 opensea-js: 7.2.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) reflect-metadata: 0.2.2 - twitter-api-v2: 1.25.0 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + twitter-api-v2: 1.27.0 + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -10737,17 +10840,17 @@ snapshots: '@coinbase/cdp-api-client@0.0.18': dependencies: - axios: 1.11.0 + axios: 1.12.2 transitivePeerDependencies: - debug - '@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@coinbase/cdp-api-client': 0.0.18 - jose: 6.0.12 + jose: 6.1.0 ox: 0.8.1(typescript@5.9.2)(zod@3.25.76) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.8(@types/react@19.1.10)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.8(@types/react@19.1.13)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -10759,35 +10862,35 @@ snapshots: - utf-8-validate - zod - '@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1)': + '@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1)': dependencies: - '@coinbase/cdp-core': 0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/cdp-core': 0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) react: 18.3.1 - '@coinbase/cdp-react@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1))(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@coinbase/cdp-react@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1))(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@coinbase/cdp-core': 0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/cdp-hooks': 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-form': 0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@coinbase/cdp-core': 0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/cdp-hooks': 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-form': 0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 transitivePeerDependencies: - '@types/react' - '@types/react-dom' - react-dom - '@coinbase/cdp-sdk@1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@coinbase/cdp-sdk@1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@solana/spl-token': 0.4.14(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) abitype: 1.0.6(typescript@5.9.2)(zod@3.25.76) - axios: 1.11.0 - axios-retry: 4.5.0(axios@1.11.0) - jose: 6.0.12 + axios: 1.12.2 + axios-retry: 4.5.0(axios@1.12.2) + jose: 6.1.0 md5: 2.3.0 uncrypto: 0.1.3 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -10797,17 +10900,17 @@ snapshots: - typescript - utf-8-validate - '@coinbase/cdp-sdk@1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@coinbase/cdp-sdk@1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@solana/spl-token': 0.4.14(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) abitype: 1.0.6(typescript@5.9.2)(zod@3.25.76) - axios: 1.11.0 - axios-retry: 4.5.0(axios@1.11.0) - jose: 6.0.12 + axios: 1.12.2 + axios-retry: 4.5.0(axios@1.12.2) + jose: 6.1.0 md5: 2.3.0 uncrypto: 0.1.3 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -10820,10 +10923,10 @@ snapshots: '@coinbase/coinbase-sdk@0.20.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@scure/bip32': 1.7.0 - abitype: 1.0.9(typescript@5.9.2)(zod@3.25.76) - axios: 1.11.0 - axios-mock-adapter: 1.22.0(axios@1.11.0) - axios-retry: 4.5.0(axios@1.11.0) + abitype: 1.1.1(typescript@5.9.2)(zod@3.25.76) + axios: 1.12.2 + axios-mock-adapter: 1.22.0(axios@1.12.2) + axios-retry: 4.5.0(axios@1.12.2) bip32: 4.0.0 bip39: 3.1.0 decimal.js: 10.6.0 @@ -10832,7 +10935,7 @@ snapshots: ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) jose: 5.10.0 secp256k1: 5.0.1 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - debug @@ -10840,12 +10943,12 @@ snapshots: - utf-8-validate - zod - '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@farcaster/frame-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@tanstack/react-query': 5.85.5(react@19.1.1) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@farcaster/frame-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@tanstack/react-query': 5.90.2(react@19.1.1) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) clsx: 2.1.1 graphql: 16.11.0 graphql-request: 6.1.0(encoding@0.1.13)(graphql@16.11.0) @@ -10853,8 +10956,8 @@ snapshots: react: 19.1.1 react-dom: 19.1.1(react@19.1.1) tailwind-merge: 2.6.0 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -10872,6 +10975,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -10886,48 +10990,70 @@ snapshots: - utf-8-validate - zod - '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - dependencies: - '@farcaster/frame-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@tanstack/react-query': 5.85.5(react@19.1.1) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@coinbase/onchainkit@1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)': + dependencies: + '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@floating-ui/react': 0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@tanstack/react-query': 5.90.2(react@19.1.1) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) clsx: 2.1.1 graphql: 16.11.0 graphql-request: 6.1.0(encoding@0.1.13)(graphql@16.11.0) qrcode: 1.5.4 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - tailwind-merge: 2.6.0 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + tailwind-merge: 3.3.1 + usehooks-ts: 3.1.1(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@farcaster/miniapp-sdk' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - '@tanstack/query-core' - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch + - '@types/react-dom' + - bufferutil + - encoding + - immer + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@coinbase/onchainkit@1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11)': + dependencies: + '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@floating-ui/react': 0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@tanstack/react-query': 5.90.2(react@19.1.1) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + clsx: 2.1.1 + graphql: 16.11.0 + graphql-request: 6.1.0(encoding@0.1.13)(graphql@16.11.0) + qrcode: 1.5.4 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + tailwind-merge: 3.3.1 + usehooks-ts: 3.1.1(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) + transitivePeerDependencies: + - '@tanstack/query-core' + - '@types/react' + - '@types/react-dom' - bufferutil - - db0 - encoding - immer - - ioredis - - supports-color - typescript - - uploadthing - use-sync-external-store - utf-8-validate - zod @@ -10941,12 +11067,12 @@ snapshots: eth-json-rpc-filters: 6.0.1 eventemitter3: 5.0.1 keccak: 3.0.4 - preact: 10.27.1 + preact: 10.27.2 sha.js: 2.4.12 transitivePeerDependencies: - supports-color - '@coinbase/wallet-sdk@4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/wallet-sdk@4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/hashes': 1.4.0 clsx: 1.2.1 @@ -10954,8 +11080,28 @@ snapshots: idb-keyval: 6.2.1 ox: 0.6.9(typescript@5.9.2)(zod@3.25.76) preact: 10.24.2 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@coinbase/wallet-sdk@4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.9.2)(zod@4.1.11) + preact: 10.24.2 + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -10966,7 +11112,7 @@ snapshots: - utf-8-validate - zod - '@coinbase/wallet-sdk@4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/wallet-sdk@4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/hashes': 1.4.0 clsx: 1.2.1 @@ -10974,8 +11120,8 @@ snapshots: idb-keyval: 6.2.1 ox: 0.6.9(typescript@5.9.2)(zod@3.25.76) preact: 10.24.2 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -10988,8 +11134,8 @@ snapshots: '@coinbase/x402@0.3.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@coinbase/cdp-sdk': 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/cdp-sdk': 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: 0.3.7(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: @@ -11000,11 +11146,11 @@ snapshots: - typescript - utf-8-validate - '@coinbase/x402@0.5.1(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@coinbase/x402@0.6.4(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@coinbase/cdp-sdk': 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - x402: 0.5.3(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@coinbase/cdp-sdk': 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + x402: 0.6.1(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -11018,11 +11164,13 @@ snapshots: - '@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/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -11037,12 +11185,13 @@ snapshots: - typescript - uploadthing - utf-8-validate + - ws '@colors/colors@1.6.0': {} - '@craftamap/esbuild-plugin-html@0.9.0(bufferutil@4.0.9)(esbuild@0.25.9)(utf-8-validate@5.0.10)': + '@craftamap/esbuild-plugin-html@0.9.0(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@5.0.10)': dependencies: - esbuild: 0.25.9 + esbuild: 0.25.10 jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) lodash: 4.17.21 transitivePeerDependencies: @@ -11051,16 +11200,16 @@ snapshots: - supports-color - utf-8-validate - '@csstools/color-helpers@5.0.2': {} + '@csstools/color-helpers@5.1.0': {} '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': dependencies: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-color-parser@3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': dependencies: - '@csstools/color-helpers': 5.0.2 + '@csstools/color-helpers': 5.1.0 '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 @@ -11106,7 +11255,7 @@ snapshots: '@electron/get@2.0.3': dependencies: - debug: 4.4.1 + debug: 4.4.3 env-paths: 2.2.1 fs-extra: 8.1.0 got: 11.8.6 @@ -11136,7 +11285,7 @@ snapshots: '@electron/notarize@2.5.0': dependencies: - debug: 4.4.1 + debug: 4.4.3 fs-extra: 9.1.0 promise-retry: 2.0.1 transitivePeerDependencies: @@ -11145,7 +11294,7 @@ snapshots: '@electron/osx-sign@1.3.1': dependencies: compare-version: 0.1.2 - debug: 4.4.1 + debug: 4.4.3 fs-extra: 10.1.0 isbinaryfile: 4.0.10 minimist: 1.2.8 @@ -11158,11 +11307,11 @@ snapshots: '@electron/node-gyp': https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2 '@malept/cross-spawn-promise': 2.0.0 chalk: 4.1.2 - debug: 4.4.1 - detect-libc: 2.0.4 + debug: 4.4.3 + detect-libc: 2.1.1 fs-extra: 10.1.0 got: 11.8.6 - node-abi: 3.75.0 + node-abi: 3.77.0 node-api-version: 0.2.1 ora: 5.4.1 read-binary-file-arch: 1.0.6 @@ -11177,9 +11326,9 @@ snapshots: dependencies: '@electron/asar': 3.2.18 '@malept/cross-spawn-promise': 2.0.0 - debug: 4.4.1 + debug: 4.4.3 dir-compare: 4.2.0 - fs-extra: 11.3.1 + fs-extra: 11.3.2 minimatch: 9.0.5 plist: 3.1.0 transitivePeerDependencies: @@ -11188,26 +11337,26 @@ snapshots: '@electron/windows-sign@1.2.2': dependencies: cross-dirname: 0.1.0 - debug: 4.4.1 - fs-extra: 11.3.1 + debug: 4.4.3 + fs-extra: 11.3.2 minimist: 1.2.8 postject: 1.0.0-alpha.6 transitivePeerDependencies: - supports-color optional: true - '@emnapi/core@1.4.5': + '@emnapi/core@1.5.0': dependencies: - '@emnapi/wasi-threads': 1.0.4 + '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.4.5': + '@emnapi/runtime@1.5.0': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.0.4': + '@emnapi/wasi-threads@1.1.0': dependencies: tslib: 2.8.1 optional: true @@ -11215,7 +11364,7 @@ snapshots: '@es-joy/jsdoccomment@0.50.2': dependencies: '@types/estree': 1.0.8 - '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/types': 8.44.1 comment-parser: 1.4.1 esquery: 1.6.0 jsdoc-type-pratt-parser: 4.1.0 @@ -11223,158 +11372,158 @@ snapshots: '@esbuild/aix-ppc64@0.19.12': optional: true - '@esbuild/aix-ppc64@0.25.9': + '@esbuild/aix-ppc64@0.25.10': optional: true '@esbuild/android-arm64@0.19.12': optional: true - '@esbuild/android-arm64@0.25.9': + '@esbuild/android-arm64@0.25.10': optional: true '@esbuild/android-arm@0.19.12': optional: true - '@esbuild/android-arm@0.25.9': + '@esbuild/android-arm@0.25.10': optional: true '@esbuild/android-x64@0.19.12': optional: true - '@esbuild/android-x64@0.25.9': + '@esbuild/android-x64@0.25.10': optional: true '@esbuild/darwin-arm64@0.19.12': optional: true - '@esbuild/darwin-arm64@0.25.9': + '@esbuild/darwin-arm64@0.25.10': optional: true '@esbuild/darwin-x64@0.19.12': optional: true - '@esbuild/darwin-x64@0.25.9': + '@esbuild/darwin-x64@0.25.10': optional: true '@esbuild/freebsd-arm64@0.19.12': optional: true - '@esbuild/freebsd-arm64@0.25.9': + '@esbuild/freebsd-arm64@0.25.10': optional: true '@esbuild/freebsd-x64@0.19.12': optional: true - '@esbuild/freebsd-x64@0.25.9': + '@esbuild/freebsd-x64@0.25.10': optional: true '@esbuild/linux-arm64@0.19.12': optional: true - '@esbuild/linux-arm64@0.25.9': + '@esbuild/linux-arm64@0.25.10': optional: true '@esbuild/linux-arm@0.19.12': optional: true - '@esbuild/linux-arm@0.25.9': + '@esbuild/linux-arm@0.25.10': optional: true '@esbuild/linux-ia32@0.19.12': optional: true - '@esbuild/linux-ia32@0.25.9': + '@esbuild/linux-ia32@0.25.10': optional: true '@esbuild/linux-loong64@0.19.12': optional: true - '@esbuild/linux-loong64@0.25.9': + '@esbuild/linux-loong64@0.25.10': optional: true '@esbuild/linux-mips64el@0.19.12': optional: true - '@esbuild/linux-mips64el@0.25.9': + '@esbuild/linux-mips64el@0.25.10': optional: true '@esbuild/linux-ppc64@0.19.12': optional: true - '@esbuild/linux-ppc64@0.25.9': + '@esbuild/linux-ppc64@0.25.10': optional: true '@esbuild/linux-riscv64@0.19.12': optional: true - '@esbuild/linux-riscv64@0.25.9': + '@esbuild/linux-riscv64@0.25.10': optional: true '@esbuild/linux-s390x@0.19.12': optional: true - '@esbuild/linux-s390x@0.25.9': + '@esbuild/linux-s390x@0.25.10': optional: true '@esbuild/linux-x64@0.19.12': optional: true - '@esbuild/linux-x64@0.25.9': + '@esbuild/linux-x64@0.25.10': optional: true - '@esbuild/netbsd-arm64@0.25.9': + '@esbuild/netbsd-arm64@0.25.10': optional: true '@esbuild/netbsd-x64@0.19.12': optional: true - '@esbuild/netbsd-x64@0.25.9': + '@esbuild/netbsd-x64@0.25.10': optional: true - '@esbuild/openbsd-arm64@0.25.9': + '@esbuild/openbsd-arm64@0.25.10': optional: true '@esbuild/openbsd-x64@0.19.12': optional: true - '@esbuild/openbsd-x64@0.25.9': + '@esbuild/openbsd-x64@0.25.10': optional: true - '@esbuild/openharmony-arm64@0.25.9': + '@esbuild/openharmony-arm64@0.25.10': optional: true '@esbuild/sunos-x64@0.19.12': optional: true - '@esbuild/sunos-x64@0.25.9': + '@esbuild/sunos-x64@0.25.10': optional: true '@esbuild/win32-arm64@0.19.12': optional: true - '@esbuild/win32-arm64@0.25.9': + '@esbuild/win32-arm64@0.25.10': optional: true '@esbuild/win32-ia32@0.19.12': optional: true - '@esbuild/win32-ia32@0.25.9': + '@esbuild/win32-ia32@0.25.10': optional: true '@esbuild/win32-x64@0.19.12': optional: true - '@esbuild/win32-x64@0.25.9': + '@esbuild/win32-x64@0.25.10': optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@8.57.1)': + '@eslint-community/eslint-utils@4.9.0(eslint@8.57.1)': dependencies: eslint: 8.57.1 eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.7.0(eslint@9.33.0(jiti@1.21.7))': + '@eslint-community/eslint-utils@4.9.0(eslint@9.36.0(jiti@1.21.7))': dependencies: - eslint: 9.33.0(jiti@1.21.7) + eslint: 9.36.0(jiti@1.21.7) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -11382,7 +11531,7 @@ snapshots: '@eslint/config-array@0.21.0': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.1 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -11396,7 +11545,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.4.1 + debug: 4.4.3 espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 @@ -11410,7 +11559,7 @@ snapshots: '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.1 + debug: 4.4.3 espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -11423,7 +11572,7 @@ snapshots: '@eslint/js@8.57.1': {} - '@eslint/js@9.33.0': {} + '@eslint/js@9.36.0': {} '@eslint/object-schema@2.1.6': {} @@ -11477,9 +11626,9 @@ snapshots: - utf-8-validate - zod - '@farcaster/frame-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@farcaster/frame-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@farcaster/quick-auth': 0.0.6(typescript@5.9.2) comlink: 4.4.2 eventemitter3: 5.0.1 @@ -11491,7 +11640,7 @@ snapshots: - utf-8-validate - zod - '@farcaster/miniapp-core@0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@farcaster/miniapp-core@0.3.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) ox: 0.4.4(typescript@5.9.2)(zod@3.25.76) @@ -11502,9 +11651,9 @@ snapshots: - typescript - utf-8-validate - '@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@farcaster/miniapp-core': 0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@farcaster/miniapp-core': 0.3.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) '@farcaster/quick-auth': 0.0.6(typescript@5.9.2) comlink: 4.4.2 eventemitter3: 5.0.1 @@ -11516,17 +11665,31 @@ snapshots: - utf-8-validate - zod - '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@farcaster/miniapp-core': 0.3.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@farcaster/quick-auth': 0.0.6(typescript@5.9.2) + comlink: 4.4.2 + eventemitter3: 5.0.1 + ox: 0.4.4(typescript@5.9.2)(zod@4.1.11) + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: - '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))': dependencies: - '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@farcaster/quick-auth@0.0.5(typescript@5.9.2)': dependencies: @@ -11544,26 +11707,48 @@ snapshots: dependencies: '@floating-ui/utils': 0.2.10 - '@floating-ui/dom@1.7.3': + '@floating-ui/dom@1.7.4': dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/utils': 0.2.10 - '@floating-ui/react-dom@2.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@floating-ui/react-dom@2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/dom': 1.7.3 + '@floating-ui/dom': 1.7.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + '@floating-ui/react-dom@2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/dom': 1.7.4 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + + '@floating-ui/react@0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@floating-ui/utils': 0.2.10 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + tabbable: 6.2.0 + '@floating-ui/utils@0.2.10': {} '@gar/promisify@1.1.3': {} - '@gemini-wallet/core@0.2.0(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@gemini-wallet/core@0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + '@metamask/rpc-errors': 7.0.2 + eventemitter3: 5.0.1 + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - supports-color + + '@gemini-wallet/core@0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))': dependencies: '@metamask/rpc-errors': 7.0.2 eventemitter3: 5.0.1 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) transitivePeerDependencies: - supports-color @@ -11575,9 +11760,9 @@ snapshots: dependencies: react: 19.1.1 - '@hono/node-server@1.19.0(hono@4.9.2)': + '@hono/node-server@1.19.4(hono@4.9.8)': dependencies: - hono: 4.9.2 + hono: 4.9.8 '@hpke/chacha20poly1305@1.7.1': dependencies: @@ -11591,15 +11776,15 @@ snapshots: '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.6': + '@humanfs/node@0.16.7': dependencies: '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/retry': 0.4.3 '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.1 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -11608,94 +11793,95 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} - '@humanwhocodes/retry@0.3.1': {} - '@humanwhocodes/retry@0.4.3': {} - '@img/sharp-darwin-arm64@0.34.3': + '@img/colour@1.0.0': + optional: true + + '@img/sharp-darwin-arm64@0.34.4': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.0 + '@img/sharp-libvips-darwin-arm64': 1.2.3 optional: true - '@img/sharp-darwin-x64@0.34.3': + '@img/sharp-darwin-x64@0.34.4': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.0 + '@img/sharp-libvips-darwin-x64': 1.2.3 optional: true - '@img/sharp-libvips-darwin-arm64@1.2.0': + '@img/sharp-libvips-darwin-arm64@1.2.3': optional: true - '@img/sharp-libvips-darwin-x64@1.2.0': + '@img/sharp-libvips-darwin-x64@1.2.3': optional: true - '@img/sharp-libvips-linux-arm64@1.2.0': + '@img/sharp-libvips-linux-arm64@1.2.3': optional: true - '@img/sharp-libvips-linux-arm@1.2.0': + '@img/sharp-libvips-linux-arm@1.2.3': optional: true - '@img/sharp-libvips-linux-ppc64@1.2.0': + '@img/sharp-libvips-linux-ppc64@1.2.3': optional: true - '@img/sharp-libvips-linux-s390x@1.2.0': + '@img/sharp-libvips-linux-s390x@1.2.3': optional: true - '@img/sharp-libvips-linux-x64@1.2.0': + '@img/sharp-libvips-linux-x64@1.2.3': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': + '@img/sharp-libvips-linuxmusl-arm64@1.2.3': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.2.0': + '@img/sharp-libvips-linuxmusl-x64@1.2.3': optional: true - '@img/sharp-linux-arm64@0.34.3': + '@img/sharp-linux-arm64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.0 + '@img/sharp-libvips-linux-arm64': 1.2.3 optional: true - '@img/sharp-linux-arm@0.34.3': + '@img/sharp-linux-arm@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.0 + '@img/sharp-libvips-linux-arm': 1.2.3 optional: true - '@img/sharp-linux-ppc64@0.34.3': + '@img/sharp-linux-ppc64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.0 + '@img/sharp-libvips-linux-ppc64': 1.2.3 optional: true - '@img/sharp-linux-s390x@0.34.3': + '@img/sharp-linux-s390x@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.0 + '@img/sharp-libvips-linux-s390x': 1.2.3 optional: true - '@img/sharp-linux-x64@0.34.3': + '@img/sharp-linux-x64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.0 + '@img/sharp-libvips-linux-x64': 1.2.3 optional: true - '@img/sharp-linuxmusl-arm64@0.34.3': + '@img/sharp-linuxmusl-arm64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 optional: true - '@img/sharp-linuxmusl-x64@0.34.3': + '@img/sharp-linuxmusl-x64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.0 + '@img/sharp-libvips-linuxmusl-x64': 1.2.3 optional: true - '@img/sharp-wasm32@0.34.3': + '@img/sharp-wasm32@0.34.4': dependencies: - '@emnapi/runtime': 1.4.5 + '@emnapi/runtime': 1.5.0 optional: true - '@img/sharp-win32-arm64@0.34.3': + '@img/sharp-win32-arm64@0.34.4': optional: true - '@img/sharp-win32-ia32@0.34.3': + '@img/sharp-win32-ia32@0.34.4': optional: true - '@img/sharp-win32-x64@0.34.3': + '@img/sharp-win32-x64@0.34.4': optional: true '@isaacs/balanced-match@4.0.1': {} @@ -11708,7 +11894,7 @@ snapshots: dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 @@ -11716,27 +11902,32 @@ snapshots: '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.30': + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 '@jup-ag/api@6.0.44': {} - '@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': + '@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': dependencies: '@cfworker/json-schema': 4.1.1 ansi-styles: 5.2.0 camelcase: 6.3.0 decamelize: 1.2.0 js-tiktoken: 1.0.21 - langsmith: 0.3.62(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + langsmith: 0.3.69(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) mustache: 4.2.0 p-queue: 6.6.2 p-retry: 4.6.2 @@ -11749,27 +11940,27 @@ snapshots: - '@opentelemetry/sdk-trace-base' - openai - '@langchain/langgraph-checkpoint@0.0.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': + '@langchain/langgraph-checkpoint@0.0.18(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': dependencies: - '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) uuid: 10.0.0 - '@langchain/langgraph-sdk@0.0.109(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@langchain/langgraph-sdk@0.0.112(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@types/json-schema': 7.0.15 p-queue: 6.6.2 p-retry: 4.6.2 uuid: 9.0.1 optionalDependencies: - '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - '@langchain/langgraph@0.2.74(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76))': + '@langchain/langgraph@0.2.74(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76))': dependencies: - '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) - '@langchain/langgraph-checkpoint': 0.0.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) - '@langchain/langgraph-sdk': 0.0.109(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@langchain/core': 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/langgraph-checkpoint': 0.0.18(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) + '@langchain/langgraph-sdk': 0.0.112(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) uuid: 10.0.0 zod: 3.25.76 optionalDependencies: @@ -11778,11 +11969,11 @@ snapshots: - react - react-dom - '@langchain/openai@0.5.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@langchain/openai@0.5.18(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) js-tiktoken: 1.0.21 - openai: 5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + openai: 5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - ws @@ -11793,12 +11984,12 @@ snapshots: dependencies: '@lit-labs/ssr-dom-shim': 1.4.0 - '@llamaindex/anthropic@0.3.23(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30)': + '@llamaindex/anthropic@0.3.25(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30)': dependencies: '@anthropic-ai/sdk': 0.58.0 '@llamaindex/core': 0.6.5 '@llamaindex/env': 0.1.30 - remeda: 2.30.0 + remeda: 2.32.0 '@llamaindex/cloud@4.0.7(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30)': dependencies: @@ -11809,7 +12000,7 @@ snapshots: '@llamaindex/core@0.6.5': dependencies: '@llamaindex/env': 0.1.30 - '@types/node': 22.17.2 + '@types/node': 22.18.6 magic-bytes.js: 1.12.1 zod: 3.25.76 zod-to-json-schema: 3.24.6(zod@3.25.76) @@ -11853,7 +12044,7 @@ snapshots: '@malept/flatpak-bundler@0.4.0': dependencies: - debug: 4.4.1 + debug: 4.4.3 fs-extra: 9.1.0 lodash: 4.17.21 tmp-promise: 3.0.3 @@ -11900,7 +12091,7 @@ snapshots: '@metamask/onboarding@1.0.1': dependencies: - bowser: 2.12.0 + bowser: 2.12.1 '@metamask/providers@16.1.0': dependencies: @@ -11928,7 +12119,7 @@ snapshots: '@metamask/rpc-errors@7.0.2': dependencies: - '@metamask/utils': 11.4.2 + '@metamask/utils': 11.8.1 fast-safe-stringify: 2.1.1 transitivePeerDependencies: - supports-color @@ -11937,12 +12128,17 @@ snapshots: '@metamask/safe-event-emitter@3.1.2': {} - '@metamask/sdk-communication-layer@0.32.0(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metamask/sdk-analytics@0.0.5': dependencies: + openapi-fetch: 0.13.8 + + '@metamask/sdk-communication-layer@0.33.1(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@metamask/sdk-analytics': 0.0.5 bufferutil: 4.0.9 cross-fetch: 4.1.0(encoding@0.1.13) date-fns: 2.30.0 - debug: 4.4.1 + debug: 4.3.4 eciesjs: 0.4.15 eventemitter2: 6.4.9 readable-stream: 3.6.2 @@ -11952,21 +12148,22 @@ snapshots: transitivePeerDependencies: - supports-color - '@metamask/sdk-install-modal-web@0.32.0': + '@metamask/sdk-install-modal-web@0.32.1': dependencies: '@paulmillr/qr': 0.2.1 - '@metamask/sdk@0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': + '@metamask/sdk@0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 '@metamask/onboarding': 1.0.1 '@metamask/providers': 16.1.0 - '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@metamask/sdk-install-modal-web': 0.32.0 + '@metamask/sdk-analytics': 0.0.5 + '@metamask/sdk-communication-layer': 0.33.1(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metamask/sdk-install-modal-web': 0.32.1 '@paulmillr/qr': 0.2.1 - bowser: 2.12.0 + bowser: 2.12.1 cross-fetch: 4.1.0(encoding@0.1.13) - debug: 4.4.1 + debug: 4.3.4 eciesjs: 0.4.15 eth-rpc-errors: 4.0.3 eventemitter2: 6.4.9 @@ -11985,15 +12182,16 @@ snapshots: '@metamask/superstruct@3.2.1': {} - '@metamask/utils@11.4.2': + '@metamask/utils@11.8.1': dependencies: '@ethereumjs/tx': 4.2.0 '@metamask/superstruct': 3.2.1 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - debug: 4.4.1 - lodash.memoize: 4.1.2 + '@types/lodash': 4.17.20 + debug: 4.4.3 + lodash: 4.17.21 pony-cause: 2.1.11 semver: 7.7.2 uuid: 9.0.1 @@ -12004,7 +12202,7 @@ snapshots: dependencies: '@ethereumjs/tx': 4.2.0 '@types/debug': 4.1.12 - debug: 4.4.1 + debug: 4.4.3 semver: 7.7.2 superstruct: 1.0.4 transitivePeerDependencies: @@ -12017,7 +12215,7 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - debug: 4.4.1 + debug: 4.3.4 pony-cause: 2.1.11 semver: 7.7.2 uuid: 9.0.1 @@ -12031,25 +12229,25 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - debug: 4.4.1 + debug: 4.3.4 pony-cause: 2.1.11 semver: 7.7.2 uuid: 9.0.1 transitivePeerDependencies: - supports-color - '@modelcontextprotocol/sdk@1.17.3': + '@modelcontextprotocol/sdk@1.18.1': dependencies: ajv: 6.12.6 content-type: 1.0.5 cors: 2.8.5 cross-spawn: 7.0.6 eventsource: 3.0.7 - eventsource-parser: 3.0.5 + eventsource-parser: 3.0.6 express: 5.1.0 express-rate-limit: 7.5.1(express@5.1.0) pkce-challenge: 5.0.0 - raw-body: 3.0.0 + raw-body: 3.0.1 zod: 3.25.76 zod-to-json-schema: 3.24.6(zod@3.25.76) transitivePeerDependencies: @@ -12057,12 +12255,12 @@ snapshots: '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@emnapi/core': 1.4.5 - '@emnapi/runtime': 1.4.5 - '@tybys/wasm-util': 0.10.0 + '@emnapi/core': 1.5.0 + '@emnapi/runtime': 1.5.0 + '@tybys/wasm-util': 0.10.1 optional: true - '@next/env@15.5.0': {} + '@next/env@15.5.4': {} '@next/eslint-plugin-next@15.1.7': dependencies: @@ -12072,28 +12270,28 @@ snapshots: dependencies: fast-glob: 3.3.1 - '@next/swc-darwin-arm64@15.5.0': + '@next/swc-darwin-arm64@15.5.4': optional: true - '@next/swc-darwin-x64@15.5.0': + '@next/swc-darwin-x64@15.5.4': optional: true - '@next/swc-linux-arm64-gnu@15.5.0': + '@next/swc-linux-arm64-gnu@15.5.4': optional: true - '@next/swc-linux-arm64-musl@15.5.0': + '@next/swc-linux-arm64-musl@15.5.4': optional: true - '@next/swc-linux-x64-gnu@15.5.0': + '@next/swc-linux-x64-gnu@15.5.4': optional: true - '@next/swc-linux-x64-musl@15.5.0': + '@next/swc-linux-x64-musl@15.5.4': optional: true - '@next/swc-win32-arm64-msvc@15.5.0': + '@next/swc-win32-arm64-msvc@15.5.4': optional: true - '@next/swc-win32-x64-msvc@15.5.0': + '@next/swc-win32-x64-msvc@15.5.4': optional: true '@noble/ciphers@1.2.1': {} @@ -12116,7 +12314,7 @@ snapshots: dependencies: '@noble/hashes': 1.7.1 - '@noble/curves@1.9.6': + '@noble/curves@1.9.1': dependencies: '@noble/hashes': 1.8.0 @@ -12173,29 +12371,29 @@ snapshots: '@pkgr/core@0.2.9': {} - '@privy-io/api-base@1.6.0': + '@privy-io/api-base@1.7.0': dependencies: zod: 3.25.76 - '@privy-io/public-api@2.43.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@privy-io/public-api@2.45.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@privy-io/api-base': 1.6.0 + '@privy-io/api-base': 1.7.0 bs58: 5.0.0 - libphonenumber-js: 1.12.13 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + libphonenumber-js: 1.12.22 + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil - typescript - utf-8-validate - '@privy-io/server-auth@1.31.1(bufferutil@4.0.9)(encoding@0.1.13)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@privy-io/server-auth@1.32.5(bufferutil@4.0.9)(encoding@0.1.13)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: '@hpke/chacha20poly1305': 1.7.1 '@hpke/core': 1.7.4 '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 - '@privy-io/public-api': 2.43.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@privy-io/public-api': 2.45.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@scure/base': 1.2.6 '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) canonicalize: 2.1.0 @@ -12203,12 +12401,12 @@ snapshots: jose: 4.15.9 node-fetch-native: 1.6.7 redaxios: 0.5.1 - svix: 1.74.1 + svix: 1.76.1 ts-case-convert: 2.1.0 type-fest: 3.13.1 optionalDependencies: ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - encoding @@ -12221,770 +12419,1096 @@ snapshots: '@radix-ui/primitive@1.1.3': {} - '@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-avatar@1.1.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-avatar@1.1.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.13)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.13)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 - '@radix-ui/react-context-menu@2.2.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-context-menu@2.2.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-context@1.1.2(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-context@1.1.2(@types/react@19.1.13)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + '@radix-ui/react-context@1.1.2(@types/react@19.1.13)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 - '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@18.3.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) + aria-hidden: 1.2.6 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@19.1.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-direction@1.1.1(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-direction@1.1.1(@types/react@19.1.13)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + '@radix-ui/react-direction@1.1.1(@types/react@19.1.13)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-focus-guards@1.1.3(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.1.13)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.1.13)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-form@0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-form@0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-label': 2.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-label': 2.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) '@radix-ui/react-icons@1.3.2(react@18.3.1)': dependencies: react: 18.3.1 - '@radix-ui/react-id@1.1.1(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-id@1.1.1(@types/react@19.1.13)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + '@radix-ui/react-id@1.1.1(@types/react@19.1.13)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 - '@radix-ui/react-label@2.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-label@2.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-menu@2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-menu@2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@18.3.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-menu@2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) + aria-hidden: 1.2.6 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@19.1.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-menubar@1.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-menubar@1.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-one-time-password-field@0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-one-time-password-field@0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-password-toggle-field@0.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-password-toggle-field@0.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-popover@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@18.3.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) + aria-hidden: 1.2.6 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@19.1.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) - - '@radix-ui/react-popper@1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@floating-ui/react-dom': 2.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) '@radix-ui/rect': 1.1.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/rect': 1.1.1 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-presence@1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-progress@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-progress@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-select@2.2.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-select@2.2.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-separator@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-separator@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-slider@1.3.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-slider@1.3.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-slot@1.2.3(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-slot@1.2.3(@types/react@19.1.13)(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 - '@radix-ui/react-switch@1.2.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-slot@1.2.3(@types/react@19.1.13)(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 + + '@radix-ui/react-switch@1.2.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-toast@1.2.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-toast@1.2.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-toast@1.2.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-toolbar@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-toolbar@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.13)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.13)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.13)(react@18.3.1)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.13)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.13)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.13)(react@19.1.1)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.13)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.13)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 - '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.1.13)(react@18.3.1)': dependencies: react: 18.3.1 use-sync-external-store: 1.5.0(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.13)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 - '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.13)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 + + '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.13)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 - '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.13)(react@18.3.1)': dependencies: '@radix-ui/rect': 1.1.1 react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 - '@radix-ui/react-use-size@1.1.1(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.13)(react@19.1.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/rect': 1.1.1 + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 + + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.13)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.13)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.13 - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) '@radix-ui/rect@1.1.1': {} - '@radix-ui/themes@3.2.1(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/themes@3.2.1(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/colors': 3.0.0 classnames: 2.5.1 - radix-ui: 1.4.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + radix-ui: 1.4.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll-bar: 2.3.8(@types/react@19.1.10)(react@18.3.1) + react-remove-scroll-bar: 2.3.8(@types/react@19.1.13)(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4)': dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4) transitivePeerDependencies: - bufferutil - typescript @@ -12995,20 +13519,31 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript - utf-8-validate - zod - '@reown/appkit-controllers@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-controllers@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13024,6 +13559,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13036,13 +13572,13 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-controllers@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-controllers@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13058,6 +13594,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13074,9 +13611,9 @@ snapshots: dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) valtio: 1.13.2(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13092,6 +13629,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13104,14 +13642,14 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-pay@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-pay@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76) lit: 3.3.0 - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13127,6 +13665,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13139,14 +13678,14 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-pay@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-pay@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) lit: 3.3.0 - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13162,6 +13701,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13197,6 +13737,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13213,12 +13754,12 @@ snapshots: dependencies: buffer: 6.0.3 - '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76)': + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) lit: 3.3.0 transitivePeerDependencies: @@ -13236,6 +13777,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13249,12 +13791,12 @@ snapshots: - valtio - zod - '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76)': + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) lit: 3.3.0 transitivePeerDependencies: @@ -13272,6 +13814,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13308,6 +13851,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13321,10 +13865,10 @@ snapshots: - valtio - zod - '@reown/appkit-ui@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-ui@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) lit: 3.3.0 qrcode: 1.5.3 @@ -13343,6 +13887,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13355,10 +13900,10 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-ui@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-ui@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) lit: 3.3.0 qrcode: 1.5.3 @@ -13377,6 +13922,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13411,6 +13957,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13423,16 +13970,16 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-utils@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76)': + '@reown/appkit-utils@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-polyfills': 1.7.8 '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13448,6 +13995,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13460,16 +14008,16 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-utils@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76)': + '@reown/appkit-utils@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@reown/appkit-polyfills': 1.7.8 '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13485,6 +14033,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13504,9 +14053,9 @@ snapshots: '@reown/appkit-polyfills': 1.7.8 '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) valtio: 1.13.2(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13522,6 +14071,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13545,21 +14095,21 @@ snapshots: - typescript - utf-8-validate - '@reown/appkit@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-pay': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-pay': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) bs58: 6.0.0 - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13575,6 +14125,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13587,21 +14138,21 @@ snapshots: - utf-8-validate - zod - '@reown/appkit@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-pay': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-pay': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) bs58: 6.0.0 - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13617,6 +14168,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13639,11 +14191,11 @@ snapshots: '@reown/appkit-ui': 1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-utils': 1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(react@19.1.1))(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) bs58: 6.0.0 valtio: 1.13.2(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13659,6 +14211,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13673,64 +14226,70 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rollup/rollup-android-arm-eabi@4.46.4': + '@rollup/rollup-android-arm-eabi@4.52.2': + optional: true + + '@rollup/rollup-android-arm64@4.52.2': optional: true - '@rollup/rollup-android-arm64@4.46.4': + '@rollup/rollup-darwin-arm64@4.52.2': optional: true - '@rollup/rollup-darwin-arm64@4.46.4': + '@rollup/rollup-darwin-x64@4.52.2': optional: true - '@rollup/rollup-darwin-x64@4.46.4': + '@rollup/rollup-freebsd-arm64@4.52.2': optional: true - '@rollup/rollup-freebsd-arm64@4.46.4': + '@rollup/rollup-freebsd-x64@4.52.2': optional: true - '@rollup/rollup-freebsd-x64@4.46.4': + '@rollup/rollup-linux-arm-gnueabihf@4.52.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.46.4': + '@rollup/rollup-linux-arm-musleabihf@4.52.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.46.4': + '@rollup/rollup-linux-arm64-gnu@4.52.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.46.4': + '@rollup/rollup-linux-arm64-musl@4.52.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.46.4': + '@rollup/rollup-linux-loong64-gnu@4.52.2': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.46.4': + '@rollup/rollup-linux-ppc64-gnu@4.52.2': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.46.4': + '@rollup/rollup-linux-riscv64-gnu@4.52.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.46.4': + '@rollup/rollup-linux-riscv64-musl@4.52.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.46.4': + '@rollup/rollup-linux-s390x-gnu@4.52.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.46.4': + '@rollup/rollup-linux-x64-gnu@4.52.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.46.4': + '@rollup/rollup-linux-x64-musl@4.52.2': optional: true - '@rollup/rollup-linux-x64-musl@4.46.4': + '@rollup/rollup-openharmony-arm64@4.52.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.46.4': + '@rollup/rollup-win32-arm64-msvc@4.52.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.46.4': + '@rollup/rollup-win32-ia32-msvc@4.52.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.46.4': + '@rollup/rollup-win32-x64-gnu@4.52.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.52.2': optional: true '@rtsao/scc@1.1.0': {} @@ -13747,10 +14306,30 @@ snapshots: - utf-8-validate - zod + '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + events: 3.3.0 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@safe-global/safe-gateway-typescript-sdk': 3.23.1 + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) transitivePeerDependencies: - bufferutil - typescript @@ -13777,7 +14356,7 @@ snapshots: '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.9.6 + '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 @@ -13807,7 +14386,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/types@4.3.2': + '@smithy/types@4.5.0': dependencies: tslib: 2.8.1 @@ -13969,14 +14548,14 @@ snapshots: '@solana/errors@2.0.0-rc.1(typescript@5.9.2)': dependencies: - chalk: 5.6.0 + chalk: 5.6.2 commander: 12.1.0 typescript: 5.9.2 '@solana/errors@2.3.0(typescript@5.9.2)': dependencies: - chalk: 5.6.0 - commander: 14.0.0 + chalk: 5.6.2 + commander: 14.0.1 typescript: 5.9.2 '@solana/fast-stable-stringify@2.3.0(typescript@5.9.2)': @@ -14240,7 +14819,7 @@ snapshots: '@solana/rpc-spec': 2.3.0(typescript@5.9.2) '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) typescript: 5.9.2 - undici-types: 7.14.0 + undici-types: 7.16.0 '@solana/rpc-types@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': dependencies: @@ -14315,7 +14894,7 @@ snapshots: - fastestsmallesttextencoderdecoder - typescript - '@solana/spl-token@0.4.13(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.4.14(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) @@ -14330,7 +14909,7 @@ snapshots: - typescript - utf-8-validate - '@solana/spl-token@0.4.13(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.4.14(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) @@ -14446,7 +15025,7 @@ snapshots: '@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 @@ -14459,7 +15038,7 @@ snapshots: fast-stable-stringify: 1.0.0 jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) node-fetch: 2.7.0(encoding@0.1.13) - rpc-websockets: 9.1.3 + rpc-websockets: 9.2.0 superstruct: 2.0.2 transitivePeerDependencies: - bufferutil @@ -14489,54 +15068,54 @@ snapshots: '@stablelib/wipe@1.0.1': {} - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 - '@svgr/babel-preset@8.1.0(@babel/core@7.28.3)': + '@svgr/babel-preset@8.1.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.3) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.28.4) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.28.4) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.28.4) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.28.4) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.28.4) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.28.4) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.4) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.4) '@svgr/core@8.1.0(typescript@5.9.2)': dependencies: - '@babel/core': 7.28.3 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@svgr/babel-preset': 8.1.0(@babel/core@7.28.4) camelcase: 6.3.0 cosmiconfig: 8.3.6(typescript@5.9.2) snake-case: 3.0.4 @@ -14546,13 +15125,13 @@ snapshots: '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 entities: 4.5.0 '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.2))': dependencies: - '@babel/core': 7.28.3 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@svgr/babel-preset': 8.1.0(@babel/core@7.28.4) '@svgr/core': 8.1.0(typescript@5.9.2) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 @@ -14570,11 +15149,11 @@ snapshots: '@svgr/webpack@8.1.0(typescript@5.9.2)': dependencies: - '@babel/core': 7.28.3 - '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.3) - '@babel/preset-env': 7.28.3(@babel/core@7.28.3) - '@babel/preset-react': 7.27.1(@babel/core@7.28.3) - '@babel/preset-typescript': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.4) + '@babel/preset-env': 7.28.3(@babel/core@7.28.4) + '@babel/preset-react': 7.27.1(@babel/core@7.28.4) + '@babel/preset-typescript': 7.27.1(@babel/core@7.28.4) '@svgr/core': 8.1.0(typescript@5.9.2) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2)) '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2))(typescript@5.9.2) @@ -14594,53 +15173,53 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tanstack/query-core@5.85.5': {} + '@tanstack/query-core@5.90.2': {} - '@tanstack/react-query@5.85.5(react@19.1.1)': + '@tanstack/react-query@5.90.2(react@19.1.1)': dependencies: - '@tanstack/query-core': 5.85.5 + '@tanstack/query-core': 5.90.2 react: 19.1.1 '@tootallnate/once@2.0.0': {} '@trysound/sax@0.2.0': {} - '@tybys/wasm-util@0.10.0': + '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 optional: true '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.17.2 + '@types/node': 22.18.6 '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 22.17.2 + '@types/node': 22.18.6 '@types/responselike': 1.0.3 '@types/chai@5.2.2': @@ -14649,7 +15228,7 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 22.17.2 + '@types/node': 22.18.6 '@types/debug@4.1.12': dependencies: @@ -14661,7 +15240,7 @@ snapshots: '@types/express-serve-static-core@5.0.7': dependencies: - '@types/node': 22.17.2 + '@types/node': 22.18.6 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 0.17.5 @@ -14674,7 +15253,7 @@ snapshots: '@types/fs-extra@9.0.13': dependencies: - '@types/node': 22.17.2 + '@types/node': 22.18.6 '@types/http-cache-semantics@4.0.4': {} @@ -14686,7 +15265,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 22.17.2 + '@types/node': 22.18.6 '@types/lodash@4.17.20': {} @@ -14696,20 +15275,20 @@ snapshots: '@types/node-fetch@2.6.13': dependencies: - '@types/node': 20.19.11 + '@types/node': 20.19.17 form-data: 4.0.4 '@types/node@12.20.55': {} - '@types/node@18.19.123': + '@types/node@18.19.127': dependencies: undici-types: 5.26.5 - '@types/node@20.19.11': + '@types/node@20.19.17': dependencies: undici-types: 6.21.0 - '@types/node@22.17.2': + '@types/node@22.18.6': dependencies: undici-types: 6.21.0 @@ -14717,13 +15296,13 @@ snapshots: dependencies: undici-types: 6.19.8 - '@types/node@24.3.0': + '@types/node@24.5.2': dependencies: - undici-types: 7.10.0 + undici-types: 7.12.0 '@types/plist@3.0.5': dependencies: - '@types/node': 22.17.2 + '@types/node': 22.18.6 xmlbuilder: 15.1.1 optional: true @@ -14731,17 +15310,17 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react-dom@19.1.7(@types/react@19.1.10)': + '@types/react-dom@19.1.9(@types/react@19.1.13)': dependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 - '@types/react@19.1.10': + '@types/react@19.1.13': dependencies: csstype: 3.1.3 '@types/responselike@1.0.3': dependencies: - '@types/node': 22.17.2 + '@types/node': 22.18.6 '@types/retry@0.12.0': {} @@ -14750,12 +15329,12 @@ snapshots: '@types/send@0.17.5': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.17.2 + '@types/node': 22.18.6 '@types/serve-static@1.15.8': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.17.2 + '@types/node': 22.18.6 '@types/send': 0.17.5 '@types/triple-beam@1.3.5': {} @@ -14771,25 +15350,25 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 22.17.2 + '@types/node': 22.18.6 '@types/ws@8.18.1': dependencies: - '@types/node': 22.17.2 + '@types/node': 22.18.6 '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.17.2 + '@types/node': 22.18.6 optional: true - '@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.40.0 - '@typescript-eslint/type-utils': 8.40.0(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/utils': 8.40.0(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.40.0 + '@typescript-eslint/parser': 8.44.1(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/type-utils': 8.44.1(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.1(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.1 eslint: 8.57.1 graphemer: 1.4.0 ignore: 7.0.5 @@ -14799,15 +15378,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.40.0 - '@typescript-eslint/type-utils': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/utils': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.40.0 - eslint: 9.33.0(jiti@1.21.7) + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/type-utils': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.1 + eslint: 9.36.0(jiti@1.21.7) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -14816,81 +15395,81 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2)': + '@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2)': dependencies: - '@typescript-eslint/scope-manager': 8.40.0 - '@typescript-eslint/types': 8.40.0 - '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.40.0 - debug: 4.4.1 + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.1 + debug: 4.4.3 eslint: 8.57.1 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2)': dependencies: - '@typescript-eslint/scope-manager': 8.40.0 - '@typescript-eslint/types': 8.40.0 - '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.40.0 - debug: 4.4.1 - eslint: 9.33.0(jiti@1.21.7) + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.1 + debug: 4.4.3 + eslint: 9.36.0(jiti@1.21.7) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.40.0(typescript@5.9.2)': + '@typescript-eslint/project-service@8.44.1(typescript@5.9.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.9.2) - '@typescript-eslint/types': 8.40.0 - debug: 4.4.1 + '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) + '@typescript-eslint/types': 8.44.1 + debug: 4.4.3 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.40.0': + '@typescript-eslint/scope-manager@8.44.1': dependencies: - '@typescript-eslint/types': 8.40.0 - '@typescript-eslint/visitor-keys': 8.40.0 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/visitor-keys': 8.44.1 - '@typescript-eslint/tsconfig-utils@8.40.0(typescript@5.9.2)': + '@typescript-eslint/tsconfig-utils@8.44.1(typescript@5.9.2)': dependencies: typescript: 5.9.2 - '@typescript-eslint/type-utils@8.40.0(eslint@8.57.1)(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.44.1(eslint@8.57.1)(typescript@5.9.2)': dependencies: - '@typescript-eslint/types': 8.40.0 - '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.40.0(eslint@8.57.1)(typescript@5.9.2) - debug: 4.4.1 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.1(eslint@8.57.1)(typescript@5.9.2) + debug: 4.4.3 eslint: 8.57.1 ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2)': dependencies: - '@typescript-eslint/types': 8.40.0 - '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) - debug: 4.4.1 - eslint: 9.33.0(jiti@1.21.7) + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + debug: 4.4.3 + eslint: 9.36.0(jiti@1.21.7) ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.40.0': {} + '@typescript-eslint/types@8.44.1': {} - '@typescript-eslint/typescript-estree@8.40.0(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.44.1(typescript@5.9.2)': dependencies: - '@typescript-eslint/project-service': 8.40.0(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.9.2) - '@typescript-eslint/types': 8.40.0 - '@typescript-eslint/visitor-keys': 8.40.0 - debug: 4.4.1 + '@typescript-eslint/project-service': 8.44.1(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/visitor-keys': 8.44.1 + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -14900,31 +15479,31 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.40.0(eslint@8.57.1)(typescript@5.9.2)': + '@typescript-eslint/utils@8.44.1(eslint@8.57.1)(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.40.0 - '@typescript-eslint/types': 8.40.0 - '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) + '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1) + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) eslint: 8.57.1 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/utils@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@1.21.7)) - '@typescript-eslint/scope-manager': 8.40.0 - '@typescript-eslint/types': 8.40.0 - '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) - eslint: 9.33.0(jiti@1.21.7) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + eslint: 9.36.0(jiti@1.21.7) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.40.0': + '@typescript-eslint/visitor-keys@8.44.1': dependencies: - '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/types': 8.44.1 eslint-visitor-keys: 4.2.1 '@ungap/structured-clone@1.3.0': {} @@ -14988,19 +15567,19 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@upstash/redis@1.35.3': + '@upstash/redis@1.35.4': dependencies: uncrypto: 0.1.3 - '@vitejs/plugin-react@4.7.0(vite@7.1.3(@types/node@24.3.0)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1))': + '@vitejs/plugin-react@4.7.0(vite@7.1.7(@types/node@24.5.2)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1))': dependencies: - '@babel/core': 7.28.3 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.4) '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 7.1.3(@types/node@24.3.0)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + vite: 7.1.7(@types/node@24.5.2)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -15009,16 +15588,16 @@ snapshots: '@types/chai': 5.2.2 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.3.1 + chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.19 optionalDependencies: - vite: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + vite: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -15033,31 +15612,32 @@ snapshots: '@vitest/snapshot@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 2.0.3 '@vitest/spy@3.2.4': dependencies: - tinyspy: 4.0.3 + tinyspy: 4.0.4 '@vitest/utils@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - loupe: 3.2.0 + loupe: 3.2.1 tinyrainbow: 2.0.0 - '@wagmi/connectors@5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': + '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)': dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@gemini-wallet/core': 0.2.0(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -15072,9 +15652,11 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@tanstack/react-query' - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15087,20 +15669,22 @@ snapshots: - uploadthing - use-sync-external-store - utf-8-validate + - wagmi - zod - '@wagmi/connectors@5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': + '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)': dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@gemini-wallet/core': 0.2.0(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -15115,9 +15699,11 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@tanstack/react-query' - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15130,20 +15716,22 @@ snapshots: - uploadthing - use-sync-external-store - utf-8-validate + - wagmi - zod - '@wagmi/connectors@5.9.4(@types/react@19.1.10)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': + '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11)': dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@gemini-wallet/core': 0.2.0(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11) + '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -15158,9 +15746,11 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@tanstack/react-query' - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15173,20 +15763,22 @@ snapshots: - uploadthing - use-sync-external-store - utf-8-validate + - wagmi - zod - '@wagmi/connectors@5.9.4(@wagmi/core@2.19.0(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': + '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@wagmi/core@2.21.1(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76))(zod@3.25.76)': dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@gemini-wallet/core': 0.2.0(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) '@walletconnect/ethereum-provider': 2.21.1(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@wagmi/core@2.21.1(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -15201,9 +15793,11 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@tanstack/react-query' - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15216,16 +15810,47 @@ snapshots: - uploadthing - use-sync-external-store - utf-8-validate + - wagmi - zod - '@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + eventemitter3: 5.0.1 + mipd: 0.0.7(typescript@5.9.2) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + optionalDependencies: + '@tanstack/query-core': 5.90.2 + typescript: 5.9.2 + transitivePeerDependencies: + - '@types/react' + - immer + - react + - use-sync-external-store + + '@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))': + dependencies: + eventemitter3: 5.0.1 + mipd: 0.0.7(typescript@5.9.2) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + zustand: 5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + optionalDependencies: + '@tanstack/query-core': 5.90.2 + typescript: 5.9.2 + transitivePeerDependencies: + - '@types/react' + - immer + - react + - use-sync-external-store + + '@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.9.2) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.0(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) optionalDependencies: - '@tanstack/query-core': 5.85.5 + '@tanstack/query-core': 5.90.2 typescript: 5.9.2 transitivePeerDependencies: - '@types/react' @@ -15233,14 +15858,14 @@ snapshots: - react - use-sync-external-store - '@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.9.2) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.0(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + zustand: 5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) optionalDependencies: - '@tanstack/query-core': 5.85.5 + '@tanstack/query-core': 5.90.2 typescript: 5.9.2 transitivePeerDependencies: - '@types/react' @@ -15248,21 +15873,21 @@ snapshots: - react - use-sync-external-store - '@walletconnect/core@2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/core@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': 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.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) '@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.0(@upstash/redis@1.35.3) - '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 @@ -15281,6 +15906,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15291,21 +15917,21 @@ snapshots: - utf-8-validate - zod - '@walletconnect/core@2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/core@2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': 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.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) '@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.1(@upstash/redis@1.35.3) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 @@ -15324,6 +15950,95 @@ snapshots: - '@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.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + 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.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@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.1(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.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/core@2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + 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.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@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.1(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.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 @@ -15338,18 +16053,18 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@reown/appkit': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) - '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) + '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -15366,6 +16081,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15378,18 +16094,18 @@ snapshots: - utf-8-validate - zod - '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: - '@reown/appkit': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) - '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) + '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -15406,6 +16122,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15425,11 +16142,11 @@ snapshots: '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) - '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) + '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -15446,6 +16163,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15505,11 +16223,11 @@ snapshots: - bufferutil - utf-8-validate - '@walletconnect/keyvaluestorage@1.1.1(@upstash/redis@1.35.3)': + '@walletconnect/keyvaluestorage@1.1.1(@upstash/redis@1.35.4)': dependencies: '@walletconnect/safe-json': 1.0.2 idb-keyval: 6.2.2 - unstorage: 1.16.1(@upstash/redis@1.35.3)(idb-keyval@6.2.2) + unstorage: 1.17.1(@upstash/redis@1.35.4)(idb-keyval@6.2.2) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -15523,6 +16241,7 @@ snapshots: - '@planetscale/database' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 @@ -15550,16 +16269,16 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/sign-client@2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/sign-client@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@walletconnect/core': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/core': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@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.0(@upstash/redis@1.35.3) - '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -15575,6 +16294,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15585,16 +16305,16 @@ snapshots: - utf-8-validate - zod - '@walletconnect/sign-client@2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/sign-client@2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: - '@walletconnect/core': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/core': 2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@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.1(@upstash/redis@1.35.3) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -15610,6 +16330,79 @@ snapshots: - '@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.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@walletconnect/core': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@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.1(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + 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.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@walletconnect/core': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@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.1(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + 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 @@ -15624,12 +16417,12 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/types@2.21.0(@upstash/redis@1.35.3)': + '@walletconnect/types@2.21.0(@upstash/redis@1.35.4)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) '@walletconnect/logger': 2.1.2 events: 3.3.0 transitivePeerDependencies: @@ -15646,18 +16439,19 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 - ioredis - uploadthing - '@walletconnect/types@2.21.1(@upstash/redis@1.35.3)': + '@walletconnect/types@2.21.1(@upstash/redis@1.35.4)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) '@walletconnect/logger': 2.1.2 events: 3.3.0 transitivePeerDependencies: @@ -15674,24 +16468,25 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 - ioredis - uploadthing - '@walletconnect/universal-provider@2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/universal-provider@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) - '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/sign-client': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -15708,6 +16503,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15719,18 +16515,18 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/universal-provider@2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) - '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/sign-client': 2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -15747,6 +16543,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15758,20 +16555,105 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/universal-provider@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) - '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - es-toolkit: 1.33.0 - events: 3.3.0 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + es-toolkit: 1.33.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 + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/universal-provider@2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + es-toolkit: 1.33.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 + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/utils@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@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.0(@upstash/redis@1.35.4) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -15786,31 +16668,36 @@ snapshots: - '@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.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/utils@2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: - '@walletconnect/events': 1.0.1 - '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) - '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - es-toolkit: 1.33.0 - events: 3.3.0 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@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.0(@upstash/redis@1.35.4) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -15825,29 +16712,29 @@ snapshots: - '@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.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/utils@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) '@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.0(@upstash/redis@1.35.3) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) '@walletconnect/window-getters': 1.0.1 '@walletconnect/window-metadata': 1.0.1 bs58: 6.0.0 @@ -15869,6 +16756,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15879,25 +16767,25 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/utils@2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) '@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.1(@upstash/redis@1.35.3) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) '@walletconnect/window-getters': 1.0.1 '@walletconnect/window-metadata': 1.0.1 bs58: 6.0.0 detect-browser: 5.3.0 query-string: 7.1.3 uint8arrays: 3.1.0 - viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -15912,6 +16800,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15940,21 +16829,41 @@ snapshots: typescript: 5.9.2 zod: 3.25.76 - abitype@1.0.8(typescript@5.9.2)(zod@3.22.4): + abitype@1.0.8(typescript@5.9.2)(zod@3.25.76): + optionalDependencies: + typescript: 5.9.2 + zod: 3.25.76 + + abitype@1.0.8(typescript@5.9.2)(zod@4.1.11): + optionalDependencies: + typescript: 5.9.2 + zod: 4.1.11 + + abitype@1.1.0(typescript@5.9.2)(zod@3.22.4): optionalDependencies: typescript: 5.9.2 zod: 3.22.4 - abitype@1.0.8(typescript@5.9.2)(zod@3.25.76): + abitype@1.1.0(typescript@5.9.2)(zod@3.25.76): optionalDependencies: typescript: 5.9.2 zod: 3.25.76 - abitype@1.0.9(typescript@5.9.2)(zod@3.25.76): + abitype@1.1.0(typescript@5.9.2)(zod@4.1.11): + optionalDependencies: + typescript: 5.9.2 + zod: 4.1.11 + + abitype@1.1.1(typescript@5.9.2)(zod@3.25.76): optionalDependencies: typescript: 5.9.2 zod: 3.25.76 + abitype@1.1.1(typescript@5.9.2)(zod@4.1.11): + optionalDependencies: + typescript: 5.9.2 + zod: 4.1.11 + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -15979,7 +16888,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -16008,13 +16917,13 @@ snapshots: ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.0.6 + fast-uri: 3.1.0 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 ansi-regex@5.0.1: {} - ansi-regex@6.2.0: {} + ansi-regex@6.2.2: {} ansi-styles@4.3.0: dependencies: @@ -16022,7 +16931,7 @@ snapshots: ansi-styles@5.2.0: {} - ansi-styles@6.2.1: {} + ansi-styles@6.2.3: {} any-promise@1.3.0: {} @@ -16051,7 +16960,7 @@ snapshots: builder-util-runtime: 9.3.1 chromium-pickle-js: 0.2.0 config-file-ts: 0.2.8-rc1 - debug: 4.4.1 + debug: 4.4.3 dmg-builder: 26.0.12(electron-builder-squirrel-windows@26.0.12) dotenv: 16.6.1 dotenv-expand: 11.0.7 @@ -16061,7 +16970,7 @@ snapshots: fs-extra: 10.1.0 hosted-git-info: 4.1.0 is-ci: 3.0.1 - isbinaryfile: 5.0.4 + isbinaryfile: 5.0.6 js-yaml: 4.1.0 json5: 2.2.3 lazy-val: 1.0.5 @@ -16191,18 +17100,18 @@ snapshots: axe-core@4.10.3: {} - axios-mock-adapter@1.22.0(axios@1.11.0): + axios-mock-adapter@1.22.0(axios@1.12.2): dependencies: - axios: 1.11.0 + axios: 1.12.2 fast-deep-equal: 3.1.3 is-buffer: 2.0.5 - axios-retry@4.5.0(axios@1.11.0): + axios-retry@4.5.0(axios@1.12.2): dependencies: - axios: 1.11.0 + axios: 1.12.2 is-retry-allowed: 2.2.0 - axios@1.11.0: + axios@1.12.2: dependencies: follow-redirects: 1.15.11 form-data: 4.0.4 @@ -16212,27 +17121,27 @@ snapshots: axobject-query@4.1.0: {} - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.3): + babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.4): dependencies: - '@babel/compat-data': 7.28.0 - '@babel/core': 7.28.3 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) + '@babel/compat-data': 7.28.4 + '@babel/core': 7.28.4 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.3): + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.4): dependencies: - '@babel/core': 7.28.3 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) core-js-compat: 3.45.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.3): + babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.4): dependencies: - '@babel/core': 7.28.3 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) transitivePeerDependencies: - supports-color @@ -16248,6 +17157,8 @@ snapshots: base64-js@1.5.1: {} + baseline-browser-mapping@2.8.6: {} + big.js@6.2.2: {} bigint-buffer@1.1.5: @@ -16304,12 +17215,12 @@ snapshots: dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 4.4.1 + debug: 4.4.3 http-errors: 2.0.0 iconv-lite: 0.6.3 on-finished: 2.4.1 qs: 6.14.0 - raw-body: 3.0.0 + raw-body: 3.0.1 type-is: 2.0.1 transitivePeerDependencies: - supports-color @@ -16325,7 +17236,7 @@ snapshots: bs58: 4.0.1 text-encoding-utf-8: 1.0.2 - bowser@2.12.0: {} + bowser@2.12.1: {} brace-expansion@1.1.12: dependencies: @@ -16342,12 +17253,13 @@ snapshots: brorand@1.1.0: {} - browserslist@4.25.3: + browserslist@4.26.2: dependencies: - caniuse-lite: 1.0.30001735 - electron-to-chromium: 1.5.207 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.3) + baseline-browser-mapping: 2.8.6 + caniuse-lite: 1.0.30001745 + electron-to-chromium: 1.5.223 + node-releases: 2.0.21 + update-browserslist-db: 1.1.3(browserslist@4.26.2) bs58@4.0.1: dependencies: @@ -16389,7 +17301,7 @@ snapshots: builder-util-runtime@9.3.1: dependencies: - debug: 4.4.1 + debug: 4.4.3 sax: 1.4.1 transitivePeerDependencies: - supports-color @@ -16402,7 +17314,7 @@ snapshots: builder-util-runtime: 9.3.1 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1 + debug: 4.4.3 fs-extra: 10.1.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 @@ -16421,9 +17333,9 @@ snapshots: esbuild: 0.19.12 load-tsconfig: 0.2.5 - bundle-require@5.1.0(esbuild@0.25.9): + bundle-require@5.1.0(esbuild@0.25.10): dependencies: - esbuild: 0.25.9 + esbuild: 0.25.10 load-tsconfig: 0.2.5 bytes@3.1.2: {} @@ -16490,16 +17402,16 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001735: {} + caniuse-lite@1.0.30001745: {} canonicalize@2.1.0: {} - chai@5.3.1: + chai@5.3.3: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.2.0 + loupe: 3.2.1 pathval: 2.0.1 chalk@4.1.2: @@ -16507,7 +17419,7 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.6.0: {} + chalk@5.6.2: {} charenc@0.0.2: {} @@ -16535,10 +17447,11 @@ snapshots: ci-info@3.9.0: {} - cipher-base@1.0.6: + cipher-base@1.0.7: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 + to-buffer: 1.2.2 classnames@2.5.1: {} @@ -16595,19 +17508,13 @@ snapshots: color-string@1.9.1: dependencies: color-name: 1.1.4 - simple-swizzle: 0.2.2 + simple-swizzle: 0.2.4 color@3.2.1: dependencies: color-convert: 1.9.3 color-string: 1.9.1 - color@4.2.3: - dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 - optional: true - colorspace@1.1.4: dependencies: color: 3.2.1 @@ -16621,7 +17528,7 @@ snapshots: commander@12.1.0: {} - commander@14.0.0: {} + commander@14.0.1: {} commander@2.20.3: {} @@ -16652,10 +17559,9 @@ snapshots: tree-kill: 1.2.2 yargs: 17.7.2 - concurrently@9.2.0: + concurrently@9.2.1: dependencies: chalk: 4.1.2 - lodash: 4.17.21 rxjs: 7.8.2 shell-quote: 1.8.3 supports-color: 8.1.1 @@ -16699,7 +17605,7 @@ snapshots: core-js-compat@3.45.1: dependencies: - browserslist: 4.25.3 + browserslist: 4.26.2 core-util-is@1.0.2: optional: true @@ -16729,10 +17635,10 @@ snapshots: create-hash@1.2.0: dependencies: - cipher-base: 1.0.6 + cipher-base: 1.0.7 inherits: 2.0.4 md5.js: 1.3.5 - ripemd160: 2.0.2 + ripemd160: 2.0.3 sha.js: 2.4.12 cross-dirname@0.1.0: @@ -16826,7 +17732,7 @@ snapshots: date-fns@2.30.0: dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 dayjs@1.11.13: {} @@ -16838,11 +17744,11 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.3.7: + debug@4.3.4: dependencies: - ms: 2.1.3 + ms: 2.1.2 - debug@4.4.1: + debug@4.4.3: dependencies: ms: 2.1.3 @@ -16888,9 +17794,9 @@ snapshots: depd@2.0.0: {} - derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1)): + derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1)): dependencies: - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) derive-valtio@0.1.0(valtio@1.13.2(react@19.1.1)): dependencies: @@ -16902,7 +17808,7 @@ snapshots: detect-browser@5.3.0: {} - detect-libc@2.0.4: {} + detect-libc@2.1.1: {} detect-node-es@1.1.0: {} @@ -17062,12 +17968,12 @@ snapshots: transitivePeerDependencies: - supports-color - electron-to-chromium@1.5.207: {} + electron-to-chromium@1.5.223: {} electron-winstaller@5.4.0: dependencies: '@electron/asar': 3.4.1 - debug: 4.4.1 + debug: 4.4.3 fs-extra: 7.0.1 lodash: 4.17.21 temp: 0.9.4 @@ -17076,10 +17982,10 @@ snapshots: transitivePeerDependencies: - supports-color - electron@37.3.1: + electron@37.5.1: dependencies: '@electron/get': 2.0.3 - '@types/node': 22.17.2 + '@types/node': 22.18.6 extract-zip: 2.0.1 transitivePeerDependencies: - supports-color @@ -17118,7 +18024,7 @@ snapshots: engine.io-client@6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 + debug: 4.3.4 engine.io-parser: 5.2.3 ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) xmlhttprequest-ssl: 2.1.2 @@ -17137,7 +18043,7 @@ snapshots: err-code@2.0.3: {} - error-ex@1.3.2: + error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 @@ -17281,34 +18187,34 @@ snapshots: '@esbuild/win32-ia32': 0.19.12 '@esbuild/win32-x64': 0.19.12 - esbuild@0.25.9: + esbuild@0.25.10: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.9 - '@esbuild/android-arm': 0.25.9 - '@esbuild/android-arm64': 0.25.9 - '@esbuild/android-x64': 0.25.9 - '@esbuild/darwin-arm64': 0.25.9 - '@esbuild/darwin-x64': 0.25.9 - '@esbuild/freebsd-arm64': 0.25.9 - '@esbuild/freebsd-x64': 0.25.9 - '@esbuild/linux-arm': 0.25.9 - '@esbuild/linux-arm64': 0.25.9 - '@esbuild/linux-ia32': 0.25.9 - '@esbuild/linux-loong64': 0.25.9 - '@esbuild/linux-mips64el': 0.25.9 - '@esbuild/linux-ppc64': 0.25.9 - '@esbuild/linux-riscv64': 0.25.9 - '@esbuild/linux-s390x': 0.25.9 - '@esbuild/linux-x64': 0.25.9 - '@esbuild/netbsd-arm64': 0.25.9 - '@esbuild/netbsd-x64': 0.25.9 - '@esbuild/openbsd-arm64': 0.25.9 - '@esbuild/openbsd-x64': 0.25.9 - '@esbuild/openharmony-arm64': 0.25.9 - '@esbuild/sunos-x64': 0.25.9 - '@esbuild/win32-arm64': 0.25.9 - '@esbuild/win32-ia32': 0.25.9 - '@esbuild/win32-x64': 0.25.9 + '@esbuild/aix-ppc64': 0.25.10 + '@esbuild/android-arm': 0.25.10 + '@esbuild/android-arm64': 0.25.10 + '@esbuild/android-x64': 0.25.10 + '@esbuild/darwin-arm64': 0.25.10 + '@esbuild/darwin-x64': 0.25.10 + '@esbuild/freebsd-arm64': 0.25.10 + '@esbuild/freebsd-x64': 0.25.10 + '@esbuild/linux-arm': 0.25.10 + '@esbuild/linux-arm64': 0.25.10 + '@esbuild/linux-ia32': 0.25.10 + '@esbuild/linux-loong64': 0.25.10 + '@esbuild/linux-mips64el': 0.25.10 + '@esbuild/linux-ppc64': 0.25.10 + '@esbuild/linux-riscv64': 0.25.10 + '@esbuild/linux-s390x': 0.25.10 + '@esbuild/linux-x64': 0.25.10 + '@esbuild/netbsd-arm64': 0.25.10 + '@esbuild/netbsd-x64': 0.25.10 + '@esbuild/openbsd-arm64': 0.25.10 + '@esbuild/openbsd-x64': 0.25.10 + '@esbuild/openharmony-arm64': 0.25.10 + '@esbuild/sunos-x64': 0.25.10 + '@esbuild/win32-arm64': 0.25.10 + '@esbuild/win32-ia32': 0.25.10 + '@esbuild/win32-x64': 0.25.10 escalade@3.2.0: {} @@ -17316,19 +18222,19 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-next@15.1.7(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2): + eslint-config-next@15.1.7(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2): dependencies: '@next/eslint-plugin-next': 15.1.7 '@rushstack/eslint-patch': 1.12.0 - '@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) - eslint: 9.33.0(jiti@1.21.7) + '@typescript-eslint/eslint-plugin': 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + eslint: 9.36.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.33.0(jiti@1.21.7)) - eslint-plugin-react: 7.37.5(eslint@9.33.0(jiti@1.21.7)) - eslint-plugin-react-hooks: 5.2.0(eslint@9.33.0(jiti@1.21.7)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.36.0(jiti@1.21.7)) + eslint-plugin-react: 7.37.5(eslint@9.36.0(jiti@1.21.7)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.36.0(jiti@1.21.7)) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -17340,12 +18246,12 @@ snapshots: dependencies: '@next/eslint-plugin-next': 15.3.3 '@rushstack/eslint-patch': 1.12.0 - '@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/eslint-plugin': 8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/parser': 8.44.1(eslint@8.57.1)(typescript@5.9.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.5(eslint@8.57.1) eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1) @@ -17360,9 +18266,9 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)): + eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)): dependencies: - eslint: 9.33.0(jiti@1.21.7) + eslint: 9.36.0(jiti@1.21.7) optional: true eslint-import-resolver-node@0.3.9: @@ -17373,59 +18279,59 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.1 + debug: 4.4.3 eslint: 8.57.1 get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)): dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.1 - eslint: 9.33.0(jiti@1.21.7) + debug: 4.4.3 + eslint: 9.36.0(jiti@1.21.7) get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/parser': 8.44.1(eslint@8.57.1)(typescript@5.9.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) - eslint: 9.33.0(jiti@1.21.7) + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + eslint: 9.36.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -17436,7 +18342,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -17448,13 +18354,13 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/parser': 8.44.1(eslint@8.57.1)(typescript@5.9.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -17463,9 +18369,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.33.0(jiti@1.21.7) + eslint: 9.36.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -17477,20 +18383,20 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsdoc@50.8.0(eslint@9.33.0(jiti@1.21.7)): + eslint-plugin-jsdoc@50.8.0(eslint@9.36.0(jiti@1.21.7)): dependencies: '@es-joy/jsdoccomment': 0.50.2 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.4.1 + debug: 4.4.3 escape-string-regexp: 4.0.0 - eslint: 9.33.0(jiti@1.21.7) + eslint: 9.36.0(jiti@1.21.7) espree: 10.4.0 esquery: 1.6.0 parse-imports-exports: 0.2.4 @@ -17518,7 +18424,7 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-jsx-a11y@6.10.2(eslint@9.33.0(jiti@1.21.7)): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.36.0(jiti@1.21.7)): dependencies: aria-query: 5.3.2 array-includes: 3.1.9 @@ -17528,7 +18434,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.33.0(jiti@1.21.7) + eslint: 9.36.0(jiti@1.21.7) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -17546,22 +18452,22 @@ snapshots: optionalDependencies: eslint-config-prettier: 10.1.8(eslint@8.57.1) - eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2): + eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2): dependencies: - eslint: 9.33.0(jiti@1.21.7) + eslint: 9.36.0(jiti@1.21.7) prettier: 3.5.2 prettier-linter-helpers: 1.0.0 synckit: 0.11.11 optionalDependencies: - eslint-config-prettier: 10.1.8(eslint@9.33.0(jiti@1.21.7)) + eslint-config-prettier: 10.1.8(eslint@9.36.0(jiti@1.21.7)) eslint-plugin-react-hooks@5.2.0(eslint@8.57.1): dependencies: eslint: 8.57.1 - eslint-plugin-react-hooks@5.2.0(eslint@9.33.0(jiti@1.21.7)): + eslint-plugin-react-hooks@5.2.0(eslint@9.36.0(jiti@1.21.7)): dependencies: - eslint: 9.33.0(jiti@1.21.7) + eslint: 9.36.0(jiti@1.21.7) eslint-plugin-react@7.37.5(eslint@8.57.1): dependencies: @@ -17585,7 +18491,7 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-react@7.37.5(eslint@9.33.0(jiti@1.21.7)): + eslint-plugin-react@7.37.5(eslint@9.36.0(jiti@1.21.7)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -17593,7 +18499,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 9.33.0(jiti@1.21.7) + eslint: 9.36.0(jiti@1.21.7) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -17623,7 +18529,7 @@ snapshots: eslint@8.57.1: dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1) '@eslint-community/regexpp': 4.12.1 '@eslint/eslintrc': 2.1.4 '@eslint/js': 8.57.1 @@ -17634,7 +18540,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1 + debug: 4.4.3 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -17664,17 +18570,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint@9.33.0(jiti@1.21.7): + eslint@9.36.0(jiti@1.21.7): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@1.21.7)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0(jiti@1.21.7)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 '@eslint/config-helpers': 0.3.1 '@eslint/core': 0.15.2 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.33.0 + '@eslint/js': 9.36.0 '@eslint/plugin-kit': 0.3.5 - '@humanfs/node': 0.16.6 + '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 @@ -17682,7 +18588,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1 + debug: 4.4.3 escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -17793,11 +18699,11 @@ snapshots: events@3.3.0: {} - eventsource-parser@3.0.5: {} + eventsource-parser@3.0.6: {} eventsource@3.0.7: dependencies: - eventsource-parser: 3.0.5 + eventsource-parser: 3.0.6 execa@5.1.1: dependencies: @@ -17863,7 +18769,7 @@ snapshots: content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.2.2 - debug: 4.4.1 + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -17894,7 +18800,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.4.1 + debug: 4.4.3 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -17939,7 +18845,7 @@ snapshots: fast-stable-stringify@1.0.0: {} - fast-uri@3.0.6: {} + fast-uri@3.1.0: {} fastestsmallesttextencoderdecoder@1.0.22: {} @@ -17996,7 +18902,7 @@ snapshots: finalhandler@2.1.0: dependencies: - debug: 4.4.1 + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 @@ -18017,9 +18923,9 @@ snapshots: fix-dts-default-cjs-exports@1.0.1: dependencies: - magic-string: 0.30.17 - mlly: 1.7.4 - rollup: 4.46.4 + magic-string: 0.30.19 + mlly: 1.8.0 + rollup: 4.52.2 flat-cache@3.2.0: dependencies: @@ -18078,7 +18984,7 @@ snapshots: jsonfile: 6.2.0 universalify: 2.0.1 - fs-extra@11.3.1: + fs-extra@11.3.2: dependencies: graceful-fs: 4.2.11 jsonfile: 6.2.0 @@ -18272,7 +19178,7 @@ snapshots: defu: 6.1.4 destr: 2.0.5 iron-webcrypto: 1.2.1 - node-mock-http: 1.0.2 + node-mock-http: 1.0.3 radix3: 1.1.2 ufo: 1.6.1 uncrypto: 0.1.3 @@ -18295,11 +19201,12 @@ snapshots: dependencies: has-symbols: 1.1.0 - hash-base@3.1.0: + hash-base@3.1.2: dependencies: inherits: 2.0.4 - readable-stream: 3.6.2 + readable-stream: 2.3.8 safe-buffer: 5.2.1 + to-buffer: 1.2.2 hash.js@1.1.7: dependencies: @@ -18316,7 +19223,7 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - hono@4.9.2: {} + hono@4.9.8: {} hosted-git-info@4.1.0: dependencies: @@ -18355,14 +19262,14 @@ snapshots: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -18374,14 +19281,14 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -18405,6 +19312,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.7.0: + dependencies: + safer-buffer: 2.1.2 + idb-keyval@6.2.1: {} idb-keyval@6.2.2: {} @@ -18458,7 +19369,7 @@ snapshots: is-arrayish@0.2.1: {} - is-arrayish@0.3.2: {} + is-arrayish@0.3.4: {} is-async-function@2.1.1: dependencies: @@ -18537,7 +19448,7 @@ snapshots: is-negative-zero@2.0.3: {} - is-network-error@1.1.0: {} + is-network-error@1.3.0: {} is-number-object@1.1.1: dependencies: @@ -18603,7 +19514,7 @@ snapshots: isbinaryfile@4.0.10: {} - isbinaryfile@5.0.4: {} + isbinaryfile@5.0.6: {} isexe@2.0.0: {} @@ -18664,7 +19575,7 @@ snapshots: jose@5.10.0: {} - jose@6.0.12: {} + jose@6.1.0: {} joycon@3.1.1: {} @@ -18691,7 +19602,7 @@ snapshots: http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.21 + nwsapi: 2.2.22 parse5: 7.3.0 rrweb-cssom: 0.8.0 saxes: 6.0.0 @@ -18709,8 +19620,6 @@ snapshots: - supports-color - utf-8-validate - jsesc@3.0.2: {} - jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -18769,7 +19678,7 @@ snapshots: kuler@2.0.0: {} - langsmith@0.3.62(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): + langsmith@0.3.69(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): dependencies: '@types/uuid': 10.0.0 chalk: 4.1.2 @@ -18779,7 +19688,7 @@ snapshots: semver: 7.7.2 uuid: 10.0.0 optionalDependencies: - openai: 5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + openai: 5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) language-subtag-registry@0.3.23: {} @@ -18796,7 +19705,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - libphonenumber-js@1.12.13: {} + libphonenumber-js@1.12.22: {} lilconfig@3.1.3: {} @@ -18827,7 +19736,7 @@ snapshots: '@llamaindex/openai': 0.3.7(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30)(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) '@llamaindex/workflow': 1.0.3(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30)(zod@3.25.76) '@types/lodash': 4.17.20 - '@types/node': 22.17.2 + '@types/node': 22.18.6 ajv: 8.17.1 lodash: 4.17.21 magic-bytes.js: 1.12.1 @@ -18852,8 +19761,6 @@ snapshots: lodash.debounce@4.0.8: {} - lodash.memoize@4.1.2: {} - lodash.merge@4.6.2: {} lodash.sortby@4.7.0: {} @@ -18878,7 +19785,7 @@ snapshots: dependencies: js-tokens: 4.0.0 - loupe@3.2.0: {} + loupe@3.2.1: {} lower-case@2.0.2: dependencies: @@ -18900,7 +19807,7 @@ snapshots: magic-bytes.js@1.12.1: {} - magic-string@0.30.17: + magic-string@0.30.19: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -18935,7 +19842,7 @@ snapshots: md5.js@1.3.5: dependencies: - hash-base: 3.1.0 + hash-base: 3.1.2 inherits: 2.0.4 safe-buffer: 5.2.1 @@ -19067,7 +19974,7 @@ snapshots: mkdirp@1.0.4: {} - mlly@1.7.4: + mlly@1.8.0: dependencies: acorn: 8.15.0 pathe: 2.0.3 @@ -19076,6 +19983,8 @@ snapshots: ms@2.0.0: {} + ms@2.1.2: {} + ms@2.1.3: {} multiformats@9.9.0: {} @@ -19100,25 +20009,25 @@ snapshots: negotiator@1.0.0: {} - next@15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + next@15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - '@next/env': 15.5.0 + '@next/env': 15.5.4 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001735 + caniuse-lite: 1.0.30001745 postcss: 8.4.31 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - styled-jsx: 5.1.6(@babel/core@7.28.3)(react@19.1.1) + styled-jsx: 5.1.6(@babel/core@7.28.4)(react@19.1.1) optionalDependencies: - '@next/swc-darwin-arm64': 15.5.0 - '@next/swc-darwin-x64': 15.5.0 - '@next/swc-linux-arm64-gnu': 15.5.0 - '@next/swc-linux-arm64-musl': 15.5.0 - '@next/swc-linux-x64-gnu': 15.5.0 - '@next/swc-linux-x64-musl': 15.5.0 - '@next/swc-win32-arm64-msvc': 15.5.0 - '@next/swc-win32-x64-msvc': 15.5.0 - sharp: 0.34.3 + '@next/swc-darwin-arm64': 15.5.4 + '@next/swc-darwin-x64': 15.5.4 + '@next/swc-linux-arm64-gnu': 15.5.4 + '@next/swc-linux-arm64-musl': 15.5.4 + '@next/swc-linux-x64-gnu': 15.5.4 + '@next/swc-linux-x64-musl': 15.5.4 + '@next/swc-win32-arm64-msvc': 15.5.4 + '@next/swc-win32-x64-msvc': 15.5.4 + sharp: 0.34.4 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -19128,7 +20037,7 @@ snapshots: lower-case: 2.0.2 tslib: 2.8.1 - node-abi@3.75.0: + node-abi@3.77.0: dependencies: semver: 7.7.2 @@ -19163,9 +20072,9 @@ snapshots: node-gyp-build@4.8.4: {} - node-mock-http@1.0.2: {} + node-mock-http@1.0.3: {} - node-releases@2.0.19: {} + node-releases@2.0.21: {} nopt@6.0.0: dependencies: @@ -19183,7 +20092,7 @@ snapshots: dependencies: boolbase: 1.0.0 - nwsapi@2.2.21: {} + nwsapi@2.2.22: {} obj-multiplex@1.0.0: dependencies: @@ -19261,7 +20170,7 @@ snapshots: openai@4.104.0(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): dependencies: - '@types/node': 18.19.123 + '@types/node': 18.19.127 '@types/node-fetch': 2.6.13 abort-controller: 3.0.0 agentkeepalive: 4.6.0 @@ -19274,11 +20183,17 @@ snapshots: transitivePeerDependencies: - encoding - openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): + openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): optionalDependencies: ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) zod: 3.25.76 + openapi-fetch@0.13.8: + dependencies: + openapi-typescript-helpers: 0.0.15 + + openapi-typescript-helpers@0.0.15: {} + opensea-js@7.2.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@opensea/seaport-js': 4.0.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -19316,12 +20231,26 @@ snapshots: ox@0.4.4(typescript@5.9.2)(zod@3.25.76): dependencies: - '@adraffy/ens-normalize': 1.11.0 + '@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.1.1(typescript@5.9.2)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - zod + + ox@0.4.4(typescript@5.9.2)(zod@4.1.11): + 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.0.9(typescript@5.9.2)(zod@3.25.76) + abitype: 1.1.1(typescript@5.9.2)(zod@4.1.11) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 @@ -19330,9 +20259,9 @@ snapshots: ox@0.6.7(typescript@5.9.2)(zod@3.25.76): dependencies: - '@adraffy/ens-normalize': 1.11.0 + '@adraffy/ens-normalize': 1.11.1 '@noble/curves': 1.8.1 - '@noble/hashes': 1.8.0 + '@noble/hashes': 1.7.1 '@scure/bip32': 1.6.2 '@scure/bip39': 1.5.4 abitype: 1.0.8(typescript@5.9.2)(zod@3.25.76) @@ -19342,14 +20271,42 @@ snapshots: transitivePeerDependencies: - zod + ox@0.6.7(typescript@5.9.2)(zod@4.1.11): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.9.2)(zod@4.1.11) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - zod + ox@0.6.9(typescript@5.9.2)(zod@3.25.76): dependencies: - '@adraffy/ens-normalize': 1.11.0 + '@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.1.1(typescript@5.9.2)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - zod + + ox@0.6.9(typescript@5.9.2)(zod@4.1.11): + 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.0.9(typescript@5.9.2)(zod@3.25.76) + abitype: 1.1.1(typescript@5.9.2)(zod@4.1.11) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 @@ -19358,43 +20315,73 @@ snapshots: ox@0.8.1(typescript@5.9.2)(zod@3.25.76): dependencies: - '@adraffy/ens-normalize': 1.11.0 + '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.0.9(typescript@5.9.2)(zod@3.25.76) + abitype: 1.1.1(typescript@5.9.2)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: - zod - ox@0.8.7(typescript@5.9.2)(zod@3.22.4): + ox@0.9.6(typescript@5.9.2)(zod@3.22.4): dependencies: - '@adraffy/ens-normalize': 1.11.0 + '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.6 + '@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@5.9.2)(zod@3.22.4) + abitype: 1.1.0(typescript@5.9.2)(zod@3.22.4) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: - zod - ox@0.8.7(typescript@5.9.2)(zod@3.25.76): + ox@0.9.6(typescript@5.9.2)(zod@3.25.76): dependencies: - '@adraffy/ens-normalize': 1.11.0 + '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.6 + '@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@5.9.2)(zod@3.25.76) + abitype: 1.1.0(typescript@5.9.2)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - zod + + ox@0.9.6(typescript@5.9.2)(zod@4.1.11): + 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.1.0(typescript@5.9.2)(zod@4.1.11) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - zod + + ox@0.9.7(typescript@5.9.2)(zod@4.1.11): + 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.1.1(typescript@5.9.2)(zod@4.1.11) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 @@ -19438,7 +20425,7 @@ snapshots: p-retry@6.2.1: dependencies: '@types/retry': 0.12.2 - is-network-error: 1.1.0 + is-network-error: 1.3.0 retry: 0.13.1 p-timeout@3.2.0: @@ -19460,7 +20447,7 @@ snapshots: parse-json@5.2.0: dependencies: '@babel/code-frame': 7.27.1 - error-ex: 1.3.2 + error-ex: 1.3.4 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -19492,7 +20479,7 @@ snapshots: path-to-regexp@0.1.12: {} - path-to-regexp@8.2.0: {} + path-to-regexp@8.3.0: {} path-type@4.0.0: {} @@ -19548,7 +20535,7 @@ snapshots: pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.7.4 + mlly: 1.8.0 pathe: 2.0.3 plist@3.1.0: @@ -19561,6 +20548,86 @@ snapshots: pony-cause@2.1.11: {} + porto@0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11)): + dependencies: + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + hono: 4.9.8 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.9.2) + ox: 0.9.7(typescript@5.9.2)(zod@4.1.11) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + zod: 4.1.11 + zustand: 5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + optionalDependencies: + '@tanstack/react-query': 5.90.2(react@19.1.1) + react: 19.1.1 + typescript: 5.9.2 + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store + + porto@0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)): + dependencies: + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + hono: 4.9.8 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.9.2) + ox: 0.9.7(typescript@5.9.2)(zod@4.1.11) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: 4.1.11 + zustand: 5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + optionalDependencies: + '@tanstack/react-query': 5.90.2(react@19.1.1) + react: 19.1.1 + typescript: 5.9.2 + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store + + porto@0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)): + dependencies: + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + hono: 4.9.8 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.9.2) + ox: 0.9.7(typescript@5.9.2)(zod@4.1.11) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: 4.1.11 + zustand: 5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + optionalDependencies: + '@tanstack/react-query': 5.90.2(react@19.1.1) + react: 19.1.1 + typescript: 5.9.2 + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store + + porto@0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@wagmi/core@2.21.1(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76)): + dependencies: + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + hono: 4.9.8 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.9.2) + ox: 0.9.7(typescript@5.9.2)(zod@4.1.11) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + zod: 4.1.11 + zustand: 5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + optionalDependencies: + '@tanstack/react-query': 5.90.2(react@19.1.1) + react: 19.1.1 + typescript: 5.9.2 + wagmi: 2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store + possible-typed-array-names@1.1.0: {} postcss-import@15.1.0(postcss@8.5.6): @@ -19570,7 +20637,7 @@ snapshots: read-cache: 1.0.0 resolve: 1.22.10 - postcss-js@4.0.1(postcss@8.5.6): + postcss-js@4.1.0(postcss@8.5.6): dependencies: camelcase-css: 2.0.1 postcss: 8.5.6 @@ -19582,13 +20649,13 @@ snapshots: optionalDependencies: postcss: 8.5.6 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(yaml@2.8.1): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(yaml@2.8.1): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 postcss: 8.5.6 - tsx: 4.20.4 + tsx: 4.20.5 yaml: 2.8.1 postcss-nested@6.2.0(postcss@8.5.6): @@ -19622,7 +20689,7 @@ snapshots: preact@10.24.2: {} - preact@10.27.1: {} + preact@10.27.2: {} prelude-ls@1.2.1: {} @@ -19709,68 +20776,68 @@ snapshots: quick-lru@5.1.1: {} - radix-ui@1.4.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + radix-ui@1.4.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-accessible-icon': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-alert-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-aspect-ratio': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-avatar': 1.1.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-context-menu': 2.2.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-form': 0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-label': 2.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-menubar': 1.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-password-toggle-field': 0.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-progress': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-radio-group': 1.3.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-select': 2.2.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slider': 1.3.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-switch': 1.2.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toolbar': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-tooltip': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-accessible-icon': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-alert-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-aspect-ratio': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-avatar': 1.1.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context-menu': 2.2.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-form': 0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-label': 2.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-menubar': 1.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-password-toggle-field': 0.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-progress': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-radio-group': 1.3.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-select': 2.2.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slider': 1.3.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-switch': 1.2.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toolbar': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tooltip': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.10 - '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) radix3@1.1.2: {} @@ -19783,11 +20850,11 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-body@3.0.0: + raw-body@3.0.1: dependencies: bytes: 3.1.2 http-errors: 2.0.0 - iconv-lite: 0.6.3 + iconv-lite: 0.7.0 unpipe: 1.0.0 react-dom@18.3.1(react@18.3.1): @@ -19818,32 +20885,59 @@ snapshots: react-refresh@0.17.0: {} - react-remove-scroll-bar@2.3.8(@types/react@19.1.10)(react@18.3.1): + react-remove-scroll-bar@2.3.8(@types/react@19.1.13)(react@18.3.1): dependencies: react: 18.3.1 - react-style-singleton: 2.2.3(@types/react@19.1.10)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@19.1.13)(react@18.3.1) tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 - react-remove-scroll@2.7.1(@types/react@19.1.10)(react@18.3.1): + react-remove-scroll-bar@2.3.8(@types/react@19.1.13)(react@19.1.1): + dependencies: + react: 19.1.1 + react-style-singleton: 2.2.3(@types/react@19.1.13)(react@19.1.1) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.13 + + react-remove-scroll@2.7.1(@types/react@19.1.13)(react@18.3.1): dependencies: react: 18.3.1 - react-remove-scroll-bar: 2.3.8(@types/react@19.1.10)(react@18.3.1) - react-style-singleton: 2.2.3(@types/react@19.1.10)(react@18.3.1) + react-remove-scroll-bar: 2.3.8(@types/react@19.1.13)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@19.1.13)(react@18.3.1) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.1.13)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@19.1.13)(react@18.3.1) + optionalDependencies: + '@types/react': 19.1.13 + + react-remove-scroll@2.7.1(@types/react@19.1.13)(react@19.1.1): + dependencies: + react: 19.1.1 + react-remove-scroll-bar: 2.3.8(@types/react@19.1.13)(react@19.1.1) + react-style-singleton: 2.2.3(@types/react@19.1.13)(react@19.1.1) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.1.10)(react@18.3.1) - use-sidecar: 1.1.3(@types/react@19.1.10)(react@18.3.1) + use-callback-ref: 1.3.3(@types/react@19.1.13)(react@19.1.1) + use-sidecar: 1.1.3(@types/react@19.1.13)(react@19.1.1) optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 - react-style-singleton@2.2.3(@types/react@19.1.10)(react@18.3.1): + react-style-singleton@2.2.3(@types/react@19.1.13)(react@18.3.1): dependencies: get-nonce: 1.0.1 react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + react-style-singleton@2.2.3(@types/react@19.1.13)(react@19.1.1): + dependencies: + get-nonce: 1.0.1 + react: 19.1.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.13 react@18.3.1: dependencies: @@ -19853,7 +20947,7 @@ snapshots: read-binary-file-arch@1.0.6: dependencies: - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -19900,7 +20994,7 @@ snapshots: get-proto: 1.0.1 which-builtin-type: 1.2.1 - regenerate-unicode-properties@10.2.0: + regenerate-unicode-properties@10.2.2: dependencies: regenerate: 1.4.2 @@ -19915,22 +21009,22 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 - regexpu-core@6.2.0: + regexpu-core@6.4.0: dependencies: regenerate: 1.4.2 - regenerate-unicode-properties: 10.2.0 + regenerate-unicode-properties: 10.2.2 regjsgen: 0.8.0 - regjsparser: 0.12.0 + regjsparser: 0.13.0 unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.2.0 + unicode-match-property-value-ecmascript: 2.2.1 regjsgen@0.8.0: {} - regjsparser@0.12.0: + regjsparser@0.13.0: dependencies: - jsesc: 3.0.2 + jsesc: 3.1.0 - remeda@2.30.0: + remeda@2.32.0: dependencies: type-fest: 4.41.0 @@ -19989,9 +21083,9 @@ snapshots: dependencies: glob: 7.2.3 - ripemd160@2.0.2: + ripemd160@2.0.3: dependencies: - hash-base: 3.1.0 + hash-base: 3.1.2 inherits: 2.0.4 roarr@2.15.4: @@ -20004,43 +21098,45 @@ snapshots: sprintf-js: 1.1.3 optional: true - rollup@4.46.4: + rollup@4.52.2: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.46.4 - '@rollup/rollup-android-arm64': 4.46.4 - '@rollup/rollup-darwin-arm64': 4.46.4 - '@rollup/rollup-darwin-x64': 4.46.4 - '@rollup/rollup-freebsd-arm64': 4.46.4 - '@rollup/rollup-freebsd-x64': 4.46.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.46.4 - '@rollup/rollup-linux-arm-musleabihf': 4.46.4 - '@rollup/rollup-linux-arm64-gnu': 4.46.4 - '@rollup/rollup-linux-arm64-musl': 4.46.4 - '@rollup/rollup-linux-loongarch64-gnu': 4.46.4 - '@rollup/rollup-linux-ppc64-gnu': 4.46.4 - '@rollup/rollup-linux-riscv64-gnu': 4.46.4 - '@rollup/rollup-linux-riscv64-musl': 4.46.4 - '@rollup/rollup-linux-s390x-gnu': 4.46.4 - '@rollup/rollup-linux-x64-gnu': 4.46.4 - '@rollup/rollup-linux-x64-musl': 4.46.4 - '@rollup/rollup-win32-arm64-msvc': 4.46.4 - '@rollup/rollup-win32-ia32-msvc': 4.46.4 - '@rollup/rollup-win32-x64-msvc': 4.46.4 + '@rollup/rollup-android-arm-eabi': 4.52.2 + '@rollup/rollup-android-arm64': 4.52.2 + '@rollup/rollup-darwin-arm64': 4.52.2 + '@rollup/rollup-darwin-x64': 4.52.2 + '@rollup/rollup-freebsd-arm64': 4.52.2 + '@rollup/rollup-freebsd-x64': 4.52.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.2 + '@rollup/rollup-linux-arm-musleabihf': 4.52.2 + '@rollup/rollup-linux-arm64-gnu': 4.52.2 + '@rollup/rollup-linux-arm64-musl': 4.52.2 + '@rollup/rollup-linux-loong64-gnu': 4.52.2 + '@rollup/rollup-linux-ppc64-gnu': 4.52.2 + '@rollup/rollup-linux-riscv64-gnu': 4.52.2 + '@rollup/rollup-linux-riscv64-musl': 4.52.2 + '@rollup/rollup-linux-s390x-gnu': 4.52.2 + '@rollup/rollup-linux-x64-gnu': 4.52.2 + '@rollup/rollup-linux-x64-musl': 4.52.2 + '@rollup/rollup-openharmony-arm64': 4.52.2 + '@rollup/rollup-win32-arm64-msvc': 4.52.2 + '@rollup/rollup-win32-ia32-msvc': 4.52.2 + '@rollup/rollup-win32-x64-gnu': 4.52.2 + '@rollup/rollup-win32-x64-msvc': 4.52.2 fsevents: 2.3.3 router@2.2.0: dependencies: - debug: 4.4.1 + debug: 4.4.3 depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 - path-to-regexp: 8.2.0 + path-to-regexp: 8.3.0 transitivePeerDependencies: - supports-color - rpc-websockets@9.1.3: + rpc-websockets@9.2.0: dependencies: '@swc/helpers': 0.5.17 '@types/uuid': 8.3.4 @@ -20145,7 +21241,7 @@ snapshots: send@1.2.0: dependencies: - debug: 4.4.1 + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -20212,36 +21308,36 @@ snapshots: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 - to-buffer: 1.2.1 + to-buffer: 1.2.2 - sharp@0.34.3: + sharp@0.34.4: dependencies: - color: 4.2.3 - detect-libc: 2.0.4 + '@img/colour': 1.0.0 + detect-libc: 2.1.1 semver: 7.7.2 optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.3 - '@img/sharp-darwin-x64': 0.34.3 - '@img/sharp-libvips-darwin-arm64': 1.2.0 - '@img/sharp-libvips-darwin-x64': 1.2.0 - '@img/sharp-libvips-linux-arm': 1.2.0 - '@img/sharp-libvips-linux-arm64': 1.2.0 - '@img/sharp-libvips-linux-ppc64': 1.2.0 - '@img/sharp-libvips-linux-s390x': 1.2.0 - '@img/sharp-libvips-linux-x64': 1.2.0 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 - '@img/sharp-libvips-linuxmusl-x64': 1.2.0 - '@img/sharp-linux-arm': 0.34.3 - '@img/sharp-linux-arm64': 0.34.3 - '@img/sharp-linux-ppc64': 0.34.3 - '@img/sharp-linux-s390x': 0.34.3 - '@img/sharp-linux-x64': 0.34.3 - '@img/sharp-linuxmusl-arm64': 0.34.3 - '@img/sharp-linuxmusl-x64': 0.34.3 - '@img/sharp-wasm32': 0.34.3 - '@img/sharp-win32-arm64': 0.34.3 - '@img/sharp-win32-ia32': 0.34.3 - '@img/sharp-win32-x64': 0.34.3 + '@img/sharp-darwin-arm64': 0.34.4 + '@img/sharp-darwin-x64': 0.34.4 + '@img/sharp-libvips-darwin-arm64': 1.2.3 + '@img/sharp-libvips-darwin-x64': 1.2.3 + '@img/sharp-libvips-linux-arm': 1.2.3 + '@img/sharp-libvips-linux-arm64': 1.2.3 + '@img/sharp-libvips-linux-ppc64': 1.2.3 + '@img/sharp-libvips-linux-s390x': 1.2.3 + '@img/sharp-libvips-linux-x64': 1.2.3 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 + '@img/sharp-libvips-linuxmusl-x64': 1.2.3 + '@img/sharp-linux-arm': 0.34.4 + '@img/sharp-linux-arm64': 0.34.4 + '@img/sharp-linux-ppc64': 0.34.4 + '@img/sharp-linux-s390x': 0.34.4 + '@img/sharp-linux-x64': 0.34.4 + '@img/sharp-linuxmusl-arm64': 0.34.4 + '@img/sharp-linuxmusl-x64': 0.34.4 + '@img/sharp-wasm32': 0.34.4 + '@img/sharp-win32-arm64': 0.34.4 + '@img/sharp-win32-ia32': 0.34.4 + '@img/sharp-win32-x64': 0.34.4 optional: true shebang-command@2.0.0: @@ -20286,9 +21382,9 @@ snapshots: signal-exit@4.1.0: {} - simple-swizzle@0.2.2: + simple-swizzle@0.2.4: dependencies: - is-arrayish: 0.3.2 + is-arrayish: 0.3.4 simple-update-notifier@2.0.0: dependencies: @@ -20323,7 +21419,7 @@ snapshots: socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 + debug: 4.3.4 engine.io-client: 6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) socket.io-parser: 4.2.4 transitivePeerDependencies: @@ -20334,14 +21430,14 @@ snapshots: socket.io-parser@4.2.4: dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 + debug: 4.3.4 transitivePeerDependencies: - supports-color socks-proxy-agent@7.0.0: dependencies: agent-base: 6.0.2 - debug: 4.4.1 + debug: 4.4.3 socks: 2.8.7 transitivePeerDependencies: - supports-color @@ -20429,7 +21525,7 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 string.prototype.includes@2.0.1: dependencies: @@ -20493,9 +21589,9 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + strip-ansi@7.1.2: dependencies: - ansi-regex: 6.2.0 + ansi-regex: 6.2.2 strip-bom@3.0.0: {} @@ -20507,12 +21603,12 @@ snapshots: dependencies: js-tokens: 9.0.1 - styled-jsx@5.1.6(@babel/core@7.28.3)(react@19.1.1): + styled-jsx@5.1.6(@babel/core@7.28.4)(react@19.1.1): dependencies: client-only: 0.0.1 react: 19.1.1 optionalDependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 sucrase@3.35.0: dependencies: @@ -20526,7 +21622,7 @@ snapshots: sumchecker@3.0.1: dependencies: - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -20556,10 +21652,10 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 - svix@1.74.1: + svix@1.76.1: dependencies: '@stablelib/base64': 1.0.1 - '@types/node': 22.17.2 + '@types/node': 22.18.6 es6-promise: 4.2.8 fast-sha256: 1.3.0 url-parse: 1.5.10 @@ -20571,8 +21667,12 @@ snapshots: dependencies: '@pkgr/core': 0.2.9 + tabbable@6.2.0: {} + tailwind-merge@2.6.0: {} + tailwind-merge@3.3.1: {} + tailwindcss@3.4.17: dependencies: '@alloc/quick-lru': 5.2.0 @@ -20591,7 +21691,7 @@ snapshots: picocolors: 1.1.1 postcss: 8.5.6 postcss-import: 15.1.0(postcss@8.5.6) - postcss-js: 4.0.1(postcss@8.5.6) + postcss-js: 4.1.0(postcss@8.5.6) postcss-load-config: 4.0.2(postcss@8.5.6) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 @@ -20645,7 +21745,7 @@ snapshots: tinyexec@0.3.2: {} - tinyglobby@0.2.14: + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 @@ -20654,7 +21754,7 @@ snapshots: tinyrainbow@2.0.0: {} - tinyspy@4.0.3: {} + tinyspy@4.0.4: {} tldts-core@6.1.86: {} @@ -20668,7 +21768,7 @@ snapshots: tmp@0.2.5: {} - to-buffer@1.2.1: + to-buffer@1.2.2: dependencies: isarray: 2.0.5 safe-buffer: 5.2.1 @@ -20739,14 +21839,14 @@ snapshots: bundle-require: 4.2.1(esbuild@0.19.12) cac: 6.7.14 chokidar: 3.6.0 - debug: 4.4.1 + debug: 4.4.3 esbuild: 0.19.12 execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 postcss-load-config: 4.0.2(postcss@8.5.6) resolve-from: 5.0.0 - rollup: 4.46.4 + rollup: 4.52.2 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tree-kill: 1.2.2 @@ -20757,24 +21857,24 @@ snapshots: - supports-color - ts-node - tsup@8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1): + tsup@8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1): dependencies: - bundle-require: 5.1.0(esbuild@0.25.9) + bundle-require: 5.1.0(esbuild@0.25.10) cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.2 - debug: 4.4.1 - esbuild: 0.25.9 + debug: 4.4.3 + esbuild: 0.25.10 fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(yaml@2.8.1) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(yaml@2.8.1) resolve-from: 5.0.0 - rollup: 4.46.4 + rollup: 4.52.2 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tinyexec: 0.3.2 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 tree-kill: 1.2.2 optionalDependencies: postcss: 8.5.6 @@ -20785,43 +21885,43 @@ snapshots: - tsx - yaml - tsx@4.20.4: + tsx@4.20.5: dependencies: - esbuild: 0.25.9 + esbuild: 0.25.10 get-tsconfig: 4.10.1 optionalDependencies: fsevents: 2.3.3 - turbo-darwin-64@2.5.6: + turbo-darwin-64@2.5.8: optional: true - turbo-darwin-arm64@2.5.6: + turbo-darwin-arm64@2.5.8: optional: true - turbo-linux-64@2.5.6: + turbo-linux-64@2.5.8: optional: true - turbo-linux-arm64@2.5.6: + turbo-linux-arm64@2.5.8: optional: true - turbo-windows-64@2.5.6: + turbo-windows-64@2.5.8: optional: true - turbo-windows-arm64@2.5.6: + turbo-windows-arm64@2.5.8: optional: true - turbo@2.5.6: + turbo@2.5.8: optionalDependencies: - turbo-darwin-64: 2.5.6 - turbo-darwin-arm64: 2.5.6 - turbo-linux-64: 2.5.6 - turbo-linux-arm64: 2.5.6 - turbo-windows-64: 2.5.6 - turbo-windows-arm64: 2.5.6 + turbo-darwin-64: 2.5.8 + turbo-darwin-arm64: 2.5.8 + turbo-linux-64: 2.5.8 + turbo-linux-arm64: 2.5.8 + turbo-windows-64: 2.5.8 + turbo-windows-arm64: 2.5.8 tweetnacl@1.0.3: {} - twitter-api-v2@1.25.0: {} + twitter-api-v2@1.27.0: {} type-check@0.4.0: dependencies: @@ -20905,20 +22005,20 @@ snapshots: undici-types@6.21.0: {} - undici-types@7.10.0: {} + undici-types@7.12.0: {} - undici-types@7.14.0: {} + undici-types@7.16.0: {} unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-match-property-ecmascript@2.0.0: dependencies: unicode-canonical-property-names-ecmascript: 2.0.1 - unicode-property-aliases-ecmascript: 2.1.0 + unicode-property-aliases-ecmascript: 2.2.0 - unicode-match-property-value-ecmascript@2.2.0: {} + unicode-match-property-value-ecmascript@2.2.1: {} - unicode-property-aliases-ecmascript@2.1.0: {} + unicode-property-aliases-ecmascript@2.2.0: {} unique-filename@2.0.1: dependencies: @@ -20958,7 +22058,7 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - unstorage@1.16.1(@upstash/redis@1.35.3)(idb-keyval@6.2.2): + unstorage@1.17.1(@upstash/redis@1.35.4)(idb-keyval@6.2.2): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 @@ -20969,12 +22069,12 @@ snapshots: ofetch: 1.4.1 ufo: 1.6.1 optionalDependencies: - '@upstash/redis': 1.35.3 + '@upstash/redis': 1.35.4 idb-keyval: 6.2.2 - update-browserslist-db@1.1.3(browserslist@4.25.3): + update-browserslist-db@1.1.3(browserslist@4.26.2): dependencies: - browserslist: 4.25.3 + browserslist: 4.26.2 escalade: 3.2.0 picocolors: 1.1.1 @@ -20987,20 +22087,35 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - use-callback-ref@1.3.3(@types/react@19.1.10)(react@18.3.1): + use-callback-ref@1.3.3(@types/react@19.1.13)(react@18.3.1): dependencies: react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + use-callback-ref@1.3.3(@types/react@19.1.13)(react@19.1.1): + dependencies: + react: 19.1.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.13 - use-sidecar@1.1.3(@types/react@19.1.10)(react@18.3.1): + use-sidecar@1.1.3(@types/react@19.1.13)(react@18.3.1): dependencies: detect-node-es: 1.1.0 react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 + + use-sidecar@1.1.3(@types/react@19.1.13)(react@19.1.1): + dependencies: + detect-node-es: 1.1.0 + react: 19.1.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.13 use-sync-external-store@1.2.0(react@19.1.1): dependencies: @@ -21019,6 +22134,11 @@ snapshots: react: 19.1.1 optional: true + usehooks-ts@3.1.1(react@19.1.1): + dependencies: + lodash.debounce: 4.0.8 + react: 19.1.1 + utf-8-validate@5.0.10: dependencies: node-gyp-build: 4.8.4 @@ -21045,13 +22165,13 @@ snapshots: valid-url@1.0.9: {} - valtio@1.13.2(@types/react@19.1.10)(react@19.1.1): + valtio@1.13.2(@types/react@19.1.13)(react@19.1.1): dependencies: - derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1)) + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1)) proxy-compare: 2.6.0 use-sync-external-store: 1.2.0(react@19.1.1) optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 react: 19.1.1 valtio@1.13.2(react@19.1.1): @@ -21088,15 +22208,32 @@ snapshots: - utf-8-validate - zod - viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4): + viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11): + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.9.2)(zod@4.1.11) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.6.7(typescript@5.9.2)(zod@4.1.11) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4): dependencies: - '@noble/curves': 1.9.6 + '@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@5.9.2)(zod@3.22.4) + abitype: 1.1.0(typescript@5.9.2)(zod@3.22.4) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.8.7(typescript@5.9.2)(zod@3.22.4) + ox: 0.9.6(typescript@5.9.2)(zod@3.22.4) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.2 @@ -21105,15 +22242,32 @@ snapshots: - utf-8-validate - zod - viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76): + viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: - '@noble/curves': 1.9.6 + '@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@5.9.2)(zod@3.25.76) + abitype: 1.1.0(typescript@5.9.2)(zod@3.25.76) + isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.9.6(typescript@5.9.2)(zod@3.25.76) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.0(typescript@5.9.2)(zod@4.1.11) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.8.7(typescript@5.9.2)(zod@3.25.76) + ox: 0.9.6(typescript@5.9.2)(zod@4.1.11) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.2 @@ -21122,13 +22276,13 @@ snapshots: - utf-8-validate - zod - vite-node@3.2.4(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1): + vite-node@3.2.4(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1): dependencies: cac: 6.7.14 - debug: 4.4.1 + debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + vite: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -21143,75 +22297,75 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)): dependencies: - debug: 4.4.1 + debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.2) optionalDependencies: - vite: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + vite: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript - vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1): + vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1): dependencies: - esbuild: 0.25.9 + esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.46.4 - tinyglobby: 0.2.14 + rollup: 4.52.2 + tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 22.17.2 + '@types/node': 22.18.6 fsevents: 2.3.3 jiti: 1.21.7 - tsx: 4.20.4 + tsx: 4.20.5 yaml: 2.8.1 - vite@7.1.3(@types/node@24.3.0)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1): + vite@7.1.7(@types/node@24.5.2)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1): dependencies: - esbuild: 0.25.9 + esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.46.4 - tinyglobby: 0.2.14 + rollup: 4.52.2 + tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.3.0 + '@types/node': 24.5.2 fsevents: 2.3.3 jiti: 1.21.7 - tsx: 4.20.4 + tsx: 4.20.5 yaml: 2.8.1 - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.3.1 - debug: 4.4.1 + chai: 5.3.3 + debug: 4.4.3 expect-type: 1.2.2 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + vite: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 22.17.2 + '@types/node': 22.18.6 jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - jiti @@ -21231,14 +22385,14 @@ snapshots: dependencies: xml-name-validator: 5.0.0 - wagmi@2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): + wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): dependencies: - '@tanstack/react-query': 5.85.5(react@19.1.1) - '@wagmi/connectors': 5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@tanstack/react-query': 5.90.2(react@19.1.1) + '@wagmi/connectors': 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -21257,6 +22411,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -21269,14 +22424,14 @@ snapshots: - utf-8-validate - zod - wagmi@2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): + wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11): dependencies: - '@tanstack/react-query': 5.85.5(react@19.1.1) - '@wagmi/connectors': 5.9.4(@types/react@19.1.10)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@tanstack/react-query': 5.90.2(react@19.1.1) + '@wagmi/connectors': 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -21295,6 +22450,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -21307,14 +22463,14 @@ snapshots: - utf-8-validate - zod - wagmi@2.16.4(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): + wagmi@2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76): dependencies: - '@tanstack/react-query': 5.85.5(react@19.1.1) - '@wagmi/connectors': 5.9.4(@wagmi/core@2.19.0(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@tanstack/react-query': 5.90.2(react@19.1.1) + '@wagmi/connectors': 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@wagmi/core@2.21.1(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76))(zod@3.25.76) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -21333,6 +22489,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -21477,9 +22634,9 @@ snapshots: wrap-ansi@8.1.0: dependencies: - ansi-styles: 6.2.1 + ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 wrappy@1.0.2: {} @@ -21505,8 +22662,8 @@ snapshots: x402-axios@0.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - axios: 1.11.0 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + axios: 1.12.2 + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: 0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: @@ -21519,7 +22676,7 @@ snapshots: x402-fetch@0.3.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: 0.3.7(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: @@ -21527,10 +22684,10 @@ snapshots: - typescript - utf-8-validate - x402-fetch@0.4.2(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): + x402-fetch@0.4.2(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - x402: 0.4.3(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + x402: 0.4.3(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -21549,6 +22706,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -21564,8 +22722,8 @@ snapshots: x402-hono@0.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - hono: 4.9.2 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + hono: 4.9.8 + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: 0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: @@ -21578,8 +22736,8 @@ snapshots: x402-hono@0.3.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - hono: 4.9.2 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + hono: 4.9.8 + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: 0.3.7(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: @@ -21589,9 +22747,9 @@ snapshots: x402@0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - '@coinbase/cdp-sdk': 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) - axios: 1.11.0 - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/cdp-sdk': 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) + axios: 1.12.2 + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -21603,17 +22761,17 @@ snapshots: x402@0.3.7(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil - typescript - utf-8-validate - x402@0.4.3(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): + x402@0.4.3(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -21632,6 +22790,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -21645,10 +22804,16 @@ snapshots: - uploadthing - utf-8-validate - x402@0.5.3(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): + x402@0.6.1(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + '@scure/base': 1.2.6 + '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(typescript@5.9.2)) + '@solana-program/token': 0.5.1(@solana/kit@2.3.0(typescript@5.9.2)) + '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(typescript@5.9.2))(@solana/sysvars@2.3.0(typescript@5.9.2)) + '@solana/kit': 2.3.0(typescript@5.9.2) + '@solana/transaction-confirmation': 2.3.0(typescript@5.9.2) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -21662,16 +22827,19 @@ snapshots: - '@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/functions' - '@vercel/kv' - aws4fetch - bufferutil - db0 - encoding + - fastestsmallesttextencoderdecoder - immer - ioredis - react @@ -21679,8 +22847,9 @@ snapshots: - typescript - uploadthing - utf-8-validate + - ws - x402@file:../../typescript/packages/x402(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): + x402@file:../../typescript/packages/x402(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: '@scure/base': 1.2.6 '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(typescript@5.9.2)) @@ -21688,8 +22857,8 @@ snapshots: '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(typescript@5.9.2))(@solana/sysvars@2.3.0(typescript@5.9.2)) '@solana/kit': 2.3.0(typescript@5.9.2) '@solana/transaction-confirmation': 2.3.0(typescript@5.9.2) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.16.4(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -21709,6 +22878,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -21790,32 +22960,46 @@ snapshots: zod@3.25.76: {} - zustand@5.0.0(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): + zod@4.1.11: {} + + zustand@5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) - zustand@5.0.0(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): + zustand@5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 react: 19.1.1 use-sync-external-store: 1.5.0(react@19.1.1) - zustand@5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): + zustand@5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) - zustand@5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): + zustand@5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 react: 19.1.1 use-sync-external-store: 1.5.0(react@19.1.1) - zustand@5.0.8(@types/react@19.1.10)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)): + zustand@5.0.8(@types/react@19.1.13)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)): optionalDependencies: - '@types/react': 19.1.10 + '@types/react': 19.1.13 react: 18.3.1 use-sync-external-store: 1.5.0(react@18.3.1) + + zustand@5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): + optionalDependencies: + '@types/react': 19.1.13 + react: 19.1.1 + use-sync-external-store: 1.4.0(react@19.1.1) + + zustand@5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): + optionalDependencies: + '@types/react': 19.1.13 + react: 19.1.1 + use-sync-external-store: 1.5.0(react@19.1.1) diff --git a/typescript/packages/x402/src/types/verify/index.ts b/typescript/packages/x402/src/types/verify/index.ts index b26fe49082..47a540f8e6 100644 --- a/typescript/packages/x402/src/types/verify/index.ts +++ b/typescript/packages/x402/src/types/verify/index.ts @@ -1,4 +1,5 @@ export * from "./x402Specs"; +export * from "./schemes"; export * from "./facilitator"; export * from "./constants"; export * from "./refiners"; diff --git a/typescript/packages/x402/src/types/verify/schemes/index.ts b/typescript/packages/x402/src/types/verify/schemes/index.ts new file mode 100644 index 0000000000..1ea1bbb8f0 --- /dev/null +++ b/typescript/packages/x402/src/types/verify/schemes/index.ts @@ -0,0 +1,2 @@ +export * from "./exact"; +export * from "./deferred"; diff --git a/typescript/site/app/facilitator/verify/route.ts b/typescript/site/app/facilitator/verify/route.ts index e825819ba4..524ab5153f 100644 --- a/typescript/site/app/facilitator/verify/route.ts +++ b/typescript/site/app/facilitator/verify/route.ts @@ -1,6 +1,6 @@ import { - PaymentPayload, - PaymentPayloadSchema, + ExactPaymentPayload as PaymentPayload, + ExactPaymentPayloadSchema as PaymentPayloadSchema, PaymentRequirements, PaymentRequirementsSchema, SupportedEVMNetworks, From 65dd41eb86c316bcd4149df47b7173a23d1deddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 17 Jul 2025 15:56:43 -0300 Subject: [PATCH 005/116] chore: better zod types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../next-advanced/app/paywall/page.tsx | 3 +- .../src/schemes/deferred/evm/client.test.ts | 23 +++--- .../x402/src/schemes/deferred/evm/client.ts | 35 +++++---- .../src/schemes/deferred/evm/facilitator.ts | 71 +++++++++++-------- .../deferred/evm/utils/paymentUtils.ts | 15 ++-- .../x402/src/types/verify/schemes/base.ts | 32 +++++++++ .../x402/src/types/verify/schemes/deferred.ts | 29 ++------ .../x402/src/types/verify/schemes/exact.ts | 17 ++++- .../x402/src/types/verify/schemes/index.ts | 1 + .../x402/src/types/verify/x402Specs.ts | 33 +++------ 10 files changed, 143 insertions(+), 116 deletions(-) create mode 100644 typescript/packages/x402/src/types/verify/schemes/base.ts diff --git a/examples/typescript/fullstack/next-advanced/app/paywall/page.tsx b/examples/typescript/fullstack/next-advanced/app/paywall/page.tsx index 9f66057337..ff7a709b37 100644 --- a/examples/typescript/fullstack/next-advanced/app/paywall/page.tsx +++ b/examples/typescript/fullstack/next-advanced/app/paywall/page.tsx @@ -3,7 +3,7 @@ import { Wallet } from "@coinbase/onchainkit/wallet"; import { useState } from "react"; import { verifyPayment } from "../actions"; -import { PaymentRequirements, PaymentPayload, UnsignedExactPaymentPayloadSchema } from "x402/types"; +import { PaymentRequirements, PaymentPayload, UnsignedExactPaymentPayloadSchema, ExactPaymentRequirementsSchema } from "x402/types"; import { preparePaymentHeader } from "x402/client"; import { getNetworkId } from "x402/shared"; import { exact } from "x402/schemes"; @@ -30,6 +30,7 @@ function PaymentForm({ const unSignedPaymentHeader = UnsignedExactPaymentPayloadSchema.parse( preparePaymentHeader(address, 1, paymentRequirements) ); + paymentRequirements = ExactPaymentRequirementsSchema.parse(paymentRequirements); const eip712Data = { types: { diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts index 2ad85fa1a7..9a72684af4 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -4,7 +4,8 @@ import { PaymentRequirements } from "../../../types/verify"; import { createPaymentHeader, preparePaymentHeader, signPaymentHeader } from "./client"; import { DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, - DeferredEvmPaymentRequirementsSchema, + DeferredPaymentPayloadSchema, + DeferredPaymentRequirementsSchema, UnsignedDeferredPaymentPayload, } from "../../../types/verify/schemes/deferred"; import { encodePayment } from "./utils/paymentUtils"; @@ -58,7 +59,7 @@ describe("preparePaymentHeader: new voucher", () => { const paymentHeader = await preparePaymentHeader(buyerAddress, 1, mockPaymentRequirements); const parsedPaymentRequirements = - DeferredEvmPaymentRequirementsSchema.parse(mockPaymentRequirements); + DeferredPaymentRequirementsSchema.parse(mockPaymentRequirements); expect(paymentHeader).toEqual({ x402Version: 1, @@ -85,6 +86,7 @@ describe("preparePaymentHeader: new voucher", () => { const requiredFields = ["id", "escrow"]; for (const field of requiredFields) { const badPaymentRequirements = structuredClone(mockPaymentRequirements); + // @ts-expect-error - TODO: fix this delete badPaymentRequirements.extra!.voucher[field]; await expect(preparePaymentHeader(buyerAddress, 1, badPaymentRequirements)).rejects.toThrow(); } @@ -94,6 +96,7 @@ describe("preparePaymentHeader: new voucher", () => { const requiredFields = ["id", "escrow"]; for (const field of requiredFields) { const badPaymentRequirements = structuredClone(mockPaymentRequirements); + // @ts-expect-error - TODO: fix this badPaymentRequirements.extra!.voucher[field] = "0x"; await expect(preparePaymentHeader(buyerAddress, 1, badPaymentRequirements)).rejects.toThrow(); } @@ -183,6 +186,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { it("should revert if voucher signature is invalid", async () => { // Inject incorrect signature into mockAggregatedPaymentRequirements const paymentRequirements = structuredClone(mockAggregatedPaymentRequirements); + // @ts-expect-error - TODO: fix this paymentRequirements.extra!.signature = "0x79ce97f6d1242aa7b6f4826efb553ed453fd6c7132c665d95bc226d5f3027dd5456d61ed1bd8da5de6cea4d8154070ff458300b6b84e0c9010f434af77ad3d291c"; @@ -205,6 +209,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { ]; for (const field of requiredFields) { const badPaymentRequirements = structuredClone(mockAggregatedPaymentRequirements); + // @ts-expect-error - TODO: fix this delete badPaymentRequirements.extra!.voucher[field]; await expect(preparePaymentHeader(buyerAddress, 1, badPaymentRequirements)).rejects.toThrow(); } @@ -224,6 +229,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { ]; for (const field of requiredFields) { const badPaymentRequirements = structuredClone(mockAggregatedPaymentRequirements); + // @ts-expect-error - TODO: fix this badPaymentRequirements.extra!.voucher[field] = "0x"; await expect(preparePaymentHeader(buyerAddress, 1, badPaymentRequirements)).rejects.toThrow(); } @@ -271,7 +277,8 @@ describe("signPaymentHeader", () => { }); it("should preserve all original fields in the signed payload", async () => { - const signedPaymentPayload = await signPaymentHeader(buyer, mockUnsignedHeader); + let signedPaymentPayload = await signPaymentHeader(buyer, mockUnsignedHeader); + signedPaymentPayload = DeferredPaymentPayloadSchema.parse(signedPaymentPayload); // Check that all original fields are preserved expect(signedPaymentPayload.x402Version).toBe(mockUnsignedHeader.x402Version); @@ -362,16 +369,6 @@ describe("createPaymentHeader", () => { ); }); - it("should handle different x402 versions", async () => { - await createPaymentHeader(buyer, 2, mockPaymentRequirements); - - expect(vi.mocked(encodePayment)).toHaveBeenCalledWith( - expect.objectContaining({ - x402Version: 2, - }), - ); - }); - it("should throw an error if signing fails", async () => { await expect(createPaymentHeader(buyer, 1, {} as PaymentRequirements)).rejects.toThrow(); }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index c1709bb442..548ef1d4a9 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -1,16 +1,14 @@ import { Address, Chain, Hex, LocalAccount, Transport } from "viem"; import { isSignerWallet, SignerWallet } from "../../../types/shared/evm"; -import { PaymentRequirements } from "../../../types/verify"; +import { PaymentPayload, PaymentRequirements, UnsignedPaymentPayload } from "../../../types/verify"; import { signVoucher, verifyVoucher } from "./sign"; import { encodePayment } from "./utils/paymentUtils"; import { DeferredEvmPayloadVoucher, DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, DeferredEvmPaymentRequirementsExtraNewVoucherSchema, - DeferredEvmPaymentRequirements, - DeferredEvmPaymentRequirementsSchema, - DeferredPaymentPayload, - UnsignedDeferredPaymentPayload, + DeferredPaymentRequirementsSchema, + UnsignedDeferredPaymentPayloadSchema, } from "../../../types/verify/schemes/deferred"; import { getNetworkId } from "../../../shared/network"; @@ -26,9 +24,8 @@ export async function preparePaymentHeader( from: Address, x402Version: number, paymentRequirements: PaymentRequirements, -): Promise { - const deferredPaymentRequirements = - DeferredEvmPaymentRequirementsSchema.parse(paymentRequirements); +): Promise { + const deferredPaymentRequirements = DeferredPaymentRequirementsSchema.parse(paymentRequirements); const voucher = deferredPaymentRequirements.extra.type === "new" @@ -38,7 +35,7 @@ export async function preparePaymentHeader( return { x402Version, scheme: "deferred", - network: paymentRequirements.network, + network: deferredPaymentRequirements.network, payload: { signature: undefined, voucher: voucher, @@ -55,7 +52,7 @@ export async function preparePaymentHeader( */ export function createNewVoucher( from: Address, - paymentRequirements: DeferredEvmPaymentRequirements, + paymentRequirements: PaymentRequirements, ): DeferredEvmPayloadVoucher { const extra = DeferredEvmPaymentRequirementsExtraNewVoucherSchema.parse( paymentRequirements.extra, @@ -83,7 +80,7 @@ export function createNewVoucher( */ export async function aggregateVoucher( from: Address, - paymentRequirements: DeferredEvmPaymentRequirements, + paymentRequirements: PaymentRequirements, ): Promise { const extra = DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema.parse( paymentRequirements.extra, @@ -115,19 +112,21 @@ export async function aggregateVoucher( * Signs a payment header using the provided client and payment requirements. * * @param client - The signer wallet instance used to sign the payment header - * @param unsignedPaymentHeader - The unsigned payment payload to be signed + * @param unsignedPaymentPayload - The unsigned payment payload to be signed * @returns A promise that resolves to the signed payment payload */ export async function signPaymentHeader( client: SignerWallet | LocalAccount, - unsignedPaymentHeader: UnsignedDeferredPaymentPayload, -): Promise { - const { signature } = await signVoucher(client, unsignedPaymentHeader.payload.voucher); + unsignedPaymentPayload: UnsignedPaymentPayload, +): Promise { + const unsignedDeferredPaymentPayload = + UnsignedDeferredPaymentPayloadSchema.parse(unsignedPaymentPayload); + const { signature } = await signVoucher(client, unsignedDeferredPaymentPayload.payload.voucher); return { - ...unsignedPaymentHeader, + ...unsignedDeferredPaymentPayload, payload: { - ...unsignedPaymentHeader.payload, + ...unsignedDeferredPaymentPayload.payload, signature, }, }; @@ -145,7 +144,7 @@ export async function createPayment | LocalAccount, x402Version: number, paymentRequirements: PaymentRequirements, -): Promise { +): Promise { const from = isSignerWallet(client) ? client.account!.address : client.address; const unsignedPaymentHeader = await preparePaymentHeader(from, x402Version, paymentRequirements); return signPaymentHeader(client, unsignedPaymentHeader); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 16a26962fe..c7cd6ac35e 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -11,9 +11,14 @@ import { import { getNetworkId } from "../../../shared"; import { getERC20Balance } from "../../../shared/evm"; import { ConnectedClient, SignerWallet } from "../../../types/shared/evm"; -import { PaymentRequirements, SettleResponse, VerifyResponse } from "../../../types/verify"; +import { + PaymentPayload, + PaymentRequirements, + SettleResponse, + VerifyResponse, +} from "../../../types/verify"; import { SCHEME } from "../../deferred"; -import { DeferredPaymentPayload } from "../../../types/verify/schemes/deferred"; +import { DeferredPaymentPayloadSchema } from "../../../types/verify/schemes/deferred"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; import { verifyVoucher } from "./sign"; @@ -33,7 +38,7 @@ import { verifyVoucher } from "./sign"; * - ✅ (on-chain) Verifies the voucher id has not been already claimed * * @param client - The public client used for blockchain interactions - * @param payload - The signed payment payload containing transfer parameters and signature + * @param paymentPayload - The signed payment payload containing transfer parameters and signature * @param paymentRequirements - The payment requirements that the payload must satisfy * @returns A ValidPaymentRequest indicating if the payment is valid and any invalidation reason */ @@ -43,51 +48,56 @@ export async function verify< account extends Account | undefined, >( client: ConnectedClient, - payload: DeferredPaymentPayload, + paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements, ): Promise { + // Verify payload is a deferred payment payload - plus type assert to DeferredPaymentPayload + paymentPayload = DeferredPaymentPayloadSchema.parse(paymentPayload); + // Verify payload matches requirements: scheme - if (payload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) { + if (paymentPayload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) { return { isValid: false, invalidReason: `unsupported_scheme`, - payer: payload.payload.voucher.buyer, + payer: paymentPayload.payload.voucher.buyer, }; } // Verify payload matches requirements: network - if (payload.network !== paymentRequirements.network) { + if (paymentPayload.network !== paymentRequirements.network) { return { isValid: false, invalidReason: `invalid_network`, - payer: payload.payload.voucher.buyer, + payer: paymentPayload.payload.voucher.buyer, }; } // Verify payload matches requirements: maxAmountRequired -- value in payload is enough to cover paymentRequirements.maxAmountRequired - if (BigInt(payload.payload.voucher.value) < BigInt(paymentRequirements.maxAmountRequired)) { + if ( + BigInt(paymentPayload.payload.voucher.value) < BigInt(paymentRequirements.maxAmountRequired) + ) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_value", - payer: payload.payload.voucher.buyer, + payer: paymentPayload.payload.voucher.buyer, }; } // Verify payload matches requirements: payTo - if (getAddress(payload.payload.voucher.seller) !== getAddress(paymentRequirements.payTo)) { + if (getAddress(paymentPayload.payload.voucher.seller) !== getAddress(paymentRequirements.payTo)) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_recipient_mismatch", - payer: payload.payload.voucher.buyer, + payer: paymentPayload.payload.voucher.buyer, }; } // Verify payload matches requirements: asset - if (payload.payload.voucher.asset !== paymentRequirements.asset) { + if (paymentPayload.payload.voucher.asset !== paymentRequirements.asset) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_asset_mismatch", - payer: payload.payload.voucher.buyer, + payer: paymentPayload.payload.voucher.buyer, }; } @@ -95,28 +105,28 @@ export async function verify< let chainId: number; try { chainId = getNetworkId(paymentRequirements.network); - if (chainId !== payload.payload.voucher.chainId) { + if (chainId !== paymentPayload.payload.voucher.chainId) { throw new Error(); } } catch { return { isValid: false, invalidReason: `invalid_deferred_evm_payload_chain_id`, - payer: payload.payload.voucher.buyer, + payer: paymentPayload.payload.voucher.buyer, }; } // Verify voucher signature is recoverable for the owner address const voucherSignatureIsValid = await verifyVoucher( - payload.payload.voucher, - payload.payload.signature as Hex, - payload.payload.voucher.buyer as Address, + paymentPayload.payload.voucher, + paymentPayload.payload.signature as Hex, + paymentPayload.payload.voucher.buyer as Address, ); if (!voucherSignatureIsValid) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_signature", - payer: payload.payload.voucher.buyer, + payer: paymentPayload.payload.voucher.buyer, }; } @@ -124,27 +134,27 @@ export async function verify< try { const balance = await getERC20Balance( client, - payload.payload.voucher.asset as Address, - payload.payload.voucher.buyer as Address, + paymentPayload.payload.voucher.asset as Address, + paymentPayload.payload.voucher.buyer as Address, ); - if (balance < BigInt(payload.payload.voucher.value)) { + if (balance < BigInt(paymentPayload.payload.voucher.value)) { throw new Error(); } } catch { return { isValid: false, invalidReason: "insufficient_funds", - payer: payload.payload.voucher.buyer, + payer: paymentPayload.payload.voucher.buyer, }; } // Verify voucher id has not been already claimed try { const isCollected = await client.readContract({ - address: payload.payload.voucher.escrow as Address, + address: paymentPayload.payload.voucher.escrow as Address, abi: deferredEscrowABI, functionName: "isCollected", - args: [payload.payload.voucher.id as Hex], + args: [paymentPayload.payload.voucher.id as Hex], }); if (isCollected) { throw new Error(); @@ -153,14 +163,14 @@ export async function verify< return { isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_already_claimed", - payer: payload.payload.voucher.buyer, + payer: paymentPayload.payload.voucher.buyer, }; } return { isValid: true, invalidReason: undefined, - payer: payload.payload.voucher.buyer, + payer: paymentPayload.payload.voucher.buyer, }; } @@ -177,9 +187,12 @@ export async function verify< */ export async function settle( wallet: SignerWallet, - paymentPayload: DeferredPaymentPayload, + paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements, ): Promise { + // Verify payload is a deferred payment payload - plus type assert to DeferredPaymentPayload + paymentPayload = DeferredPaymentPayloadSchema.parse(paymentPayload); + // re-verify to ensure the payment is still valid const valid = await verify(wallet, paymentPayload, paymentRequirements); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts index 0e2e63cd9d..163bace907 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts @@ -1,8 +1,6 @@ import { safeBase64Encode, safeBase64Decode } from "../../../../shared"; -import { - DeferredPaymentPayload, - DeferredPaymentPayloadSchema, -} from "../../../../types/verify/schemes/deferred"; +import { PaymentPayload } from "../../../../types/verify"; +import { DeferredPaymentPayloadSchema } from "../../../../types/verify/schemes/deferred"; /** * Encodes a payment payload into a base64 string, ensuring bigint values are properly stringified @@ -10,13 +8,14 @@ import { * @param payment - The payment payload to encode * @returns A base64 encoded string representation of the payment payload */ -export function encodePayment(payment: DeferredPaymentPayload): string { +export function encodePayment(payment: PaymentPayload): string { + const deferredPayment = DeferredPaymentPayloadSchema.parse(payment); const safe = { - ...payment, + ...deferredPayment, payload: { ...payment.payload, voucher: Object.fromEntries( - Object.entries(payment.payload.voucher).map(([key, value]) => [ + Object.entries(deferredPayment.payload.voucher).map(([key, value]) => [ key, typeof value === "bigint" ? (value as bigint).toString() : value, ]), @@ -32,7 +31,7 @@ export function encodePayment(payment: DeferredPaymentPayload): string { * @param payment - The base64 encoded payment string to decode * @returns The decoded and validated PaymentPayload object */ -export function decodePayment(payment: string): DeferredPaymentPayload { +export function decodePayment(payment: string): PaymentPayload { const decoded = safeBase64Decode(payment); const parsed = JSON.parse(decoded); diff --git a/typescript/packages/x402/src/types/verify/schemes/base.ts b/typescript/packages/x402/src/types/verify/schemes/base.ts new file mode 100644 index 0000000000..c9ddff8b42 --- /dev/null +++ b/typescript/packages/x402/src/types/verify/schemes/base.ts @@ -0,0 +1,32 @@ +import { z } from "zod"; +import { x402Versions } from "../versions"; +import { NetworkSchema } from "../../shared/network"; +import { isInteger } from "../refiners"; +import { EvmAddressRegex, MixedAddressRegex } from "../constants"; +import { SvmAddressRegex } from "../../shared/svm"; + +export const EvmOrSvmAddress = z + .string() + .regex(EvmAddressRegex) + .or(z.string().regex(SvmAddressRegex)); +export const MixedAddressOrSvmAddress = z + .string() + .regex(MixedAddressRegex) + .or(z.string().regex(SvmAddressRegex)); + +export const BasePaymentPayloadSchema = z.object({ + x402Version: z.number().refine(val => x402Versions.includes(val as 1)), + network: NetworkSchema, +}); + +export const BasePaymentRequirementsSchema = z.object({ + network: NetworkSchema, + maxAmountRequired: z.string().refine(isInteger), + resource: z.string().url(), + description: z.string(), + mimeType: z.string(), + outputSchema: z.record(z.any()).optional(), + payTo: EvmOrSvmAddress, + maxTimeoutSeconds: z.number().int(), + asset: MixedAddressOrSvmAddress, +}); diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 3835c2a620..c3a67258fe 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -4,11 +4,9 @@ import { EvmSignatureRegex, HexEncoded64ByteRegex, EvmMaxAtomicUnits, - MixedAddressRegex, } from "../constants"; import { hasMaxLength, isInteger } from "../refiners"; -import { NetworkSchema } from "../../shared"; -import { x402Versions } from "../versions"; +import { BasePaymentPayloadSchema, BasePaymentRequirementsSchema } from "./base"; export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_network_mismatch", @@ -42,20 +40,16 @@ export const DeferredEvmPayloadSchema = z.object({ }); export type DeferredEvmPayload = z.infer; -// x402DeferredEvmPaymentPayload -export const DeferredPaymentPayloadSchema = z.object({ - x402Version: z.number().refine(val => x402Versions.includes(val as 1)), +// x402DeferredPaymentPayload +export const DeferredPaymentPayloadSchema = BasePaymentPayloadSchema.extend({ scheme: z.literal("deferred"), - network: NetworkSchema, payload: DeferredEvmPayloadSchema, }); export type DeferredPaymentPayload = z.infer; // x402UnsignedDeferredPaymentPayload -export const UnsignedDeferredPaymentPayloadSchema = z.object({ - x402Version: z.number().refine(val => x402Versions.includes(val as 1)), +export const UnsignedDeferredPaymentPayloadSchema = BasePaymentPayloadSchema.extend({ scheme: z.literal("deferred"), - network: NetworkSchema, payload: DeferredEvmPayloadSchema.omit({ signature: true }).extend({ signature: z.undefined(), }), @@ -81,21 +75,12 @@ export type DeferredEvmPaymentRequirementsExtraAggregationVoucher = z.infer< typeof DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema >; -// x402DeferredEvmPaymentRequirements -export const DeferredEvmPaymentRequirementsSchema = z.object({ +// x402DeferredPaymentRequirements +export const DeferredPaymentRequirementsSchema = BasePaymentRequirementsSchema.extend({ scheme: z.literal("deferred"), - network: NetworkSchema, - maxAmountRequired: z.string().refine(isInteger), - resource: z.string().url(), - description: z.string(), - mimeType: z.string(), - outputSchema: z.record(z.any()).optional(), - payTo: z.string().regex(MixedAddressRegex), - maxTimeoutSeconds: z.number().int(), - asset: z.string().regex(MixedAddressRegex), extra: z.discriminatedUnion("type", [ DeferredEvmPaymentRequirementsExtraNewVoucherSchema, DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, ]), }); -export type DeferredEvmPaymentRequirements = z.infer; +export type DeferredPaymentRequirements = z.infer; diff --git a/typescript/packages/x402/src/types/verify/schemes/exact.ts b/typescript/packages/x402/src/types/verify/schemes/exact.ts index f7e0550e84..e77a53b8fa 100644 --- a/typescript/packages/x402/src/types/verify/schemes/exact.ts +++ b/typescript/packages/x402/src/types/verify/schemes/exact.ts @@ -9,6 +9,7 @@ import { hasMaxLength, isInteger } from "../refiners"; import { Base64EncodedRegex } from "../../../shared"; import { NetworkSchema } from "../../shared"; import { x402Versions } from "../versions"; +import { BasePaymentPayloadSchema, BasePaymentRequirementsSchema } from "./base"; export const ExactErrorReasons = [ "invalid_exact_evm_payload_authorization_valid_after", @@ -78,12 +79,22 @@ export const ExactPaymentPayloadSchema = z.object({ export type ExactPaymentPayload = z.infer; // x402UnsignedPaymentPayload -export const UnsignedExactPaymentPayloadSchema = z.object({ - x402Version: z.number().refine(val => x402Versions.includes(val as 1)), +export const UnsignedExactPaymentPayloadSchema = BasePaymentPayloadSchema.extend({ scheme: z.literal("exact"), - network: NetworkSchema, payload: ExactEvmPayloadSchema.omit({ signature: true }).extend({ signature: z.undefined(), }), }); export type UnsignedExactPaymentPayload = z.infer; + +// x402ExactPaymentRequirements +export const ExactPaymentRequirementsSchema = BasePaymentRequirementsSchema.extend({ + scheme: z.literal("exact"), + extra: z + .object({ + name: z.string().optional(), + version: z.string().optional(), + }) + .optional(), +}); +export type ExactPaymentRequirements = z.infer; diff --git a/typescript/packages/x402/src/types/verify/schemes/index.ts b/typescript/packages/x402/src/types/verify/schemes/index.ts index 1ea1bbb8f0..70740d00e5 100644 --- a/typescript/packages/x402/src/types/verify/schemes/index.ts +++ b/typescript/packages/x402/src/types/verify/schemes/index.ts @@ -1,2 +1,3 @@ +export * from "./base"; export * from "./exact"; export * from "./deferred"; diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index 34a9b15e51..099318d236 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -1,19 +1,20 @@ import { z } from "zod"; import { NetworkSchema } from "../shared"; -import { SvmAddressRegex } from "../shared/svm"; -import { isInteger } from "./refiners"; -import { EvmAddressRegex, MixedAddressRegex } from "./constants"; +import { MixedAddressRegex } from "./constants"; import { ExactErrorReasons, ExactPaymentPayloadSchema, + ExactPaymentRequirementsSchema, UnsignedExactPaymentPayloadSchema, } from "./schemes/exact"; import { DeferredErrorReasons, DeferredPaymentPayloadSchema, + DeferredPaymentRequirementsSchema, UnsignedDeferredPaymentPayloadSchema, } from "./schemes/deferred"; import { x402Versions } from "./versions"; +import { EvmOrSvmAddress } from ".."; // Enums export const schemes = ["exact", "deferred"] as const; @@ -37,24 +38,10 @@ export const ErrorReasons = [ ] as const; // x402PaymentRequirements -const EvmOrSvmAddress = z.string().regex(EvmAddressRegex).or(z.string().regex(SvmAddressRegex)); -const mixedAddressOrSvmAddress = z - .string() - .regex(MixedAddressRegex) - .or(z.string().regex(SvmAddressRegex)); -export const PaymentRequirementsSchema = z.object({ - scheme: z.enum(schemes), - network: NetworkSchema, - maxAmountRequired: z.string().refine(isInteger), - resource: z.string().url(), - description: z.string(), - mimeType: z.string(), - outputSchema: z.record(z.any()).optional(), - payTo: EvmOrSvmAddress, - maxTimeoutSeconds: z.number().int(), - asset: mixedAddressOrSvmAddress, - extra: z.record(z.any()).optional(), -}); +export const PaymentRequirementsSchema = z.discriminatedUnion("scheme", [ + ExactPaymentRequirementsSchema, + DeferredPaymentRequirementsSchema, +]); export type PaymentRequirements = z.infer; // x402PaymentPayload @@ -63,6 +50,8 @@ export const PaymentPayloadSchema = z.discriminatedUnion("scheme", [ DeferredPaymentPayloadSchema, ]); export type PaymentPayload = z.infer; + +// x402UnsignedPaymentPayload export const UnsignedPaymentPayloadSchema = z.discriminatedUnion("scheme", [ UnsignedExactPaymentPayloadSchema, UnsignedDeferredPaymentPayloadSchema, @@ -156,7 +145,7 @@ export const SettleResponseSchema = z.object({ errorReason: z.enum(ErrorReasons).optional(), payer: EvmOrSvmAddress.optional(), transaction: z.string().regex(MixedAddressRegex), - network: NetworkSchema, + network: NetworkSchema.optional(), }); export type SettleResponse = z.infer; From e93414515a899c7d6224a0398738ce1feaf782a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 17 Jul 2025 16:52:04 -0300 Subject: [PATCH 006/116] chore: rename voucher value to valueAggregate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/client.test.ts | 26 +++++++++---------- .../x402/src/schemes/deferred/evm/client.ts | 8 +++--- .../src/schemes/deferred/evm/facilitator.ts | 5 ++-- .../src/schemes/deferred/evm/sign.test.ts | 4 +-- .../x402/src/schemes/deferred/evm/sign.ts | 4 +-- .../x402/src/schemes/exact/evm/sign.ts | 8 ++++-- .../x402/src/types/shared/evm/typedData.ts | 2 +- .../x402/src/types/verify/schemes/deferred.ts | 2 +- 8 files changed, 33 insertions(+), 26 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts index 9a72684af4..0a9849f32b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -71,7 +71,7 @@ describe("preparePaymentHeader: new voucher", () => { id: voucherId, buyer: buyerAddress, seller: sellerAddress, - value: parsedPaymentRequirements.maxAmountRequired, + valueAggregate: parsedPaymentRequirements.maxAmountRequired, asset: assetAddress, timestamp: expect.any(Number), nonce: 0, @@ -122,12 +122,12 @@ describe("preparePaymentHeader: aggregated voucher", () => { extra: { type: "aggregation", signature: - "0xca991563e3929ae2027b7c8bda0fc580ad1c2390f7831ae814a2b5ec5c31e22d7e5efced8d66dd7eccb5fba63e85ffa6ae1583b0c5e85c2baf1a3aaf639e465f1c", + "0xabf0d28a3df19861fb7b4624d775a8e9064f3d8b285a8c26c5dfd03f445bd1c8331b706a3ac742068bbb1e08795cf0ea7c7e8cb81a715362005f7cde52e2b7e31c", voucher: { id: voucherId, buyer: buyerAddress, seller: sellerAddress, - value: "1000000", + valueAggregate: "1000000", asset: assetAddress, timestamp: 1715769600, nonce: 0, @@ -169,9 +169,9 @@ describe("preparePaymentHeader: aggregated voucher", () => { id: voucherId, buyer: buyerAddress, seller: sellerAddress, - value: ( + valueAggregate: ( BigInt(mockAggregatedPaymentRequirements.maxAmountRequired) + - BigInt(parsedExtra.voucher.value) + BigInt(parsedExtra.voucher.valueAggregate) ).toString(), asset: assetAddress, timestamp: expect.any(Number), @@ -200,7 +200,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { "id", "buyer", "seller", - "value", + "valueAggregate", "asset", "timestamp", "nonce", @@ -220,7 +220,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { "id", "buyer", "seller", - "value", + "valueAggregate", "asset", "timestamp", "nonce", @@ -252,7 +252,7 @@ describe("signPaymentHeader", () => { id: voucherId, buyer: buyerAddress, seller: sellerAddress, - value: "1000000", + valueAggregate: "1000000", asset: assetAddress, timestamp: 1715769600, nonce: 0, @@ -262,7 +262,7 @@ describe("signPaymentHeader", () => { }, }; const mockVoucherSignature = - "0xca991563e3929ae2027b7c8bda0fc580ad1c2390f7831ae814a2b5ec5c31e22d7e5efced8d66dd7eccb5fba63e85ffa6ae1583b0c5e85c2baf1a3aaf639e465f1c"; + "0xabf0d28a3df19861fb7b4624d775a8e9064f3d8b285a8c26c5dfd03f445bd1c8331b706a3ac742068bbb1e08795cf0ea7c7e8cb81a715362005f7cde52e2b7e31c"; it("should sign the payment header and return a complete payload", async () => { const signedPaymentPayload = await signPaymentHeader(buyer, mockUnsignedHeader); @@ -307,12 +307,12 @@ describe("createPaymentHeader", () => { extra: { type: "aggregation", signature: - "0xca991563e3929ae2027b7c8bda0fc580ad1c2390f7831ae814a2b5ec5c31e22d7e5efced8d66dd7eccb5fba63e85ffa6ae1583b0c5e85c2baf1a3aaf639e465f1c", + "0xabf0d28a3df19861fb7b4624d775a8e9064f3d8b285a8c26c5dfd03f445bd1c8331b706a3ac742068bbb1e08795cf0ea7c7e8cb81a715362005f7cde52e2b7e31c", voucher: { id: voucherId, buyer: buyerAddress, seller: sellerAddress, - value: "1000000", + valueAggregate: "1000000", asset: assetAddress, timestamp: 1715769600, nonce: 0, @@ -333,7 +333,7 @@ describe("createPaymentHeader", () => { id: voucherId, buyer: buyerAddress, seller: sellerAddress, - value: "2000000", + valueAggregate: "2000000", asset: assetAddress, timestamp: 1715769600, nonce: 1, @@ -357,7 +357,7 @@ describe("createPaymentHeader", () => { id: mockSignedPayment.payload.voucher.id, buyer: mockSignedPayment.payload.voucher.buyer, seller: mockSignedPayment.payload.voucher.seller, - value: mockSignedPayment.payload.voucher.value, + valueAggregate: mockSignedPayment.payload.voucher.valueAggregate, asset: mockSignedPayment.payload.voucher.asset, timestamp: expect.any(Number), nonce: mockSignedPayment.payload.voucher.nonce, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index 548ef1d4a9..b90cddbe38 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -62,7 +62,7 @@ export function createNewVoucher( id: extra.voucher.id, buyer: from, seller: paymentRequirements.payTo, - value: paymentRequirements.maxAmountRequired, + valueAggregate: paymentRequirements.maxAmountRequired, asset: paymentRequirements.asset, timestamp: Math.floor(Date.now() / 1000), nonce: 0, @@ -92,14 +92,16 @@ export async function aggregateVoucher( throw new Error("Invalid voucher signature"); } - const { id, escrow, buyer, seller, value, asset, nonce, chainId } = extra.voucher; + const { id, escrow, buyer, seller, valueAggregate, asset, nonce, chainId } = extra.voucher; const newTimestamp = Math.floor(Date.now() / 1000); return { id, buyer, seller, - value: (BigInt(paymentRequirements.maxAmountRequired) + BigInt(value)).toString(), + valueAggregate: ( + BigInt(paymentRequirements.maxAmountRequired) + BigInt(valueAggregate) + ).toString(), asset, timestamp: newTimestamp, nonce: nonce + 1, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index c7cd6ac35e..1c7947c2e6 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -74,7 +74,8 @@ export async function verify< // Verify payload matches requirements: maxAmountRequired -- value in payload is enough to cover paymentRequirements.maxAmountRequired if ( - BigInt(paymentPayload.payload.voucher.value) < BigInt(paymentRequirements.maxAmountRequired) + BigInt(paymentPayload.payload.voucher.valueAggregate) < + BigInt(paymentRequirements.maxAmountRequired) ) { return { isValid: false, @@ -137,7 +138,7 @@ export async function verify< paymentPayload.payload.voucher.asset as Address, paymentPayload.payload.voucher.buyer as Address, ); - if (balance < BigInt(paymentPayload.payload.voucher.value)) { + if (balance < BigInt(paymentPayload.payload.voucher.valueAggregate)) { throw new Error(); } } catch { diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts index 778cd00eda..b5ad80fe8b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts @@ -18,7 +18,7 @@ describe("voucher signature", () => { id: voucherId, buyer: buyerAddress, seller: sellerAddress, - value: "1000000", + valueAggregate: "1000000", asset: assetAddress, timestamp: 1715769600, nonce: 0, @@ -27,7 +27,7 @@ describe("voucher signature", () => { }; const mockVoucherSignature = - "0xca991563e3929ae2027b7c8bda0fc580ad1c2390f7831ae814a2b5ec5c31e22d7e5efced8d66dd7eccb5fba63e85ffa6ae1583b0c5e85c2baf1a3aaf639e465f1c"; + "0xabf0d28a3df19861fb7b4624d775a8e9064f3d8b285a8c26c5dfd03f445bd1c8331b706a3ac742068bbb1e08795cf0ea7c7e8cb81a715362005f7cde52e2b7e31c"; beforeEach(() => { vi.useFakeTimers(); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts index d5b4eb07c7..6777341b9b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts @@ -19,7 +19,7 @@ export async function signVoucher | LocalAccount, voucher: DeferredEvmPayloadVoucher, ): Promise<{ signature: Hex }> { - const { id, buyer, seller, value, asset, timestamp, nonce, escrow, chainId } = voucher; + const { id, buyer, seller, valueAggregate, asset, timestamp, nonce, escrow, chainId } = voucher; const data = { types: typedDataTypes, primaryType: deferredVoucherPrimaryType, @@ -33,7 +33,7 @@ export async function signVoucher( walletClient: SignerWallet | LocalAccount, { from, to, value, validAfter, validBefore, nonce }: ExactEvmPayloadAuthorization, - { asset, network, extra }: PaymentRequirements, + paymentRequirements: PaymentRequirements, ): Promise<{ signature: Hex }> { + const { asset, network, extra } = ExactPaymentRequirementsSchema.parse(paymentRequirements); const chainId = getNetworkId(network); const name = extra?.name; const version = extra?.version; diff --git a/typescript/packages/x402/src/types/shared/evm/typedData.ts b/typescript/packages/x402/src/types/shared/evm/typedData.ts index 959e4492e2..44a5d49696 100644 --- a/typescript/packages/x402/src/types/shared/evm/typedData.ts +++ b/typescript/packages/x402/src/types/shared/evm/typedData.ts @@ -11,7 +11,7 @@ export const typedDataTypes = { { name: "id", type: "bytes32" }, { name: "buyer", type: "address" }, { name: "seller", type: "address" }, - { name: "value", type: "uint256" }, + { name: "valueAggregate", type: "uint256" }, { name: "asset", type: "address" }, { name: "timestamp", type: "uint256" }, { name: "nonce", type: "uint256" }, diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index c3a67258fe..b3032b27b0 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -24,7 +24,7 @@ export const DeferredEvmPayloadVoucherSchema = z.object({ id: z.string().regex(HexEncoded64ByteRegex), buyer: z.string().regex(EvmAddressRegex), seller: z.string().regex(EvmAddressRegex), - value: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + valueAggregate: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), asset: z.string().regex(EvmAddressRegex), timestamp: z.number().int().nonnegative(), nonce: z.number().int().nonnegative(), From 5c35c7b3ea394547bdf81138bb662614116c568b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 17 Jul 2025 17:05:48 -0300 Subject: [PATCH 007/116] fix: implement proper value check for vouchers on verify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/facilitator.ts | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 1c7947c2e6..bee3e3fd13 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -72,16 +72,35 @@ export async function verify< }; } - // Verify payload matches requirements: maxAmountRequired -- value in payload is enough to cover paymentRequirements.maxAmountRequired - if ( - BigInt(paymentPayload.payload.voucher.valueAggregate) < - BigInt(paymentRequirements.maxAmountRequired) - ) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_value", - payer: paymentPayload.payload.voucher.buyer, - }; + // Verify payload matches requirements: maxAmountRequired -- new vouchers + // value in voucher should be enough to cover paymentRequirements.maxAmountRequired + if (paymentRequirements.extra.type === "new") { + if ( + BigInt(paymentPayload.payload.voucher.valueAggregate) < + BigInt(paymentRequirements.maxAmountRequired) + ) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_value", + payer: paymentPayload.payload.voucher.buyer, + }; + } + } + + // Verify payload matches requirements: maxAmountRequired -- aggregate vouchers + // value in voucher should be enough to cover paymentRequirements.maxAmountRequired plus previous voucher value + if (paymentRequirements.extra.type === "aggregation") { + if ( + BigInt(paymentPayload.payload.voucher.valueAggregate) < + BigInt(paymentRequirements.maxAmountRequired) + + BigInt(paymentRequirements.extra.voucher.valueAggregate) + ) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_value", + payer: paymentPayload.payload.voucher.buyer, + }; + } } // Verify payload matches requirements: payTo From a63d0e15a047c9ce5d905de4708fdd2626af6929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 17 Jul 2025 17:13:23 -0300 Subject: [PATCH 008/116] fix: remove throw empty error pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/facilitator.ts | 36 +++++++++++++------ .../x402/src/types/verify/schemes/deferred.ts | 1 + .../x402/src/types/verify/x402Specs.ts | 2 ++ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index bee3e3fd13..587a9ed3fa 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -125,10 +125,14 @@ export async function verify< let chainId: number; try { chainId = getNetworkId(paymentRequirements.network); - if (chainId !== paymentPayload.payload.voucher.chainId) { - throw new Error(); - } } catch { + return { + isValid: false, + invalidReason: `invalid_network_unsupported`, + payer: paymentPayload.payload.voucher.buyer, + }; + } + if (chainId !== paymentPayload.payload.voucher.chainId) { return { isValid: false, invalidReason: `invalid_deferred_evm_payload_chain_id`, @@ -151,16 +155,21 @@ export async function verify< } // Verify buyer has sufficient asset balance + let balance: bigint; try { - const balance = await getERC20Balance( + balance = await getERC20Balance( client, paymentPayload.payload.voucher.asset as Address, paymentPayload.payload.voucher.buyer as Address, ); - if (balance < BigInt(paymentPayload.payload.voucher.valueAggregate)) { - throw new Error(); - } } catch { + return { + isValid: false, + invalidReason: "insufficient_funds_contract_call_failed", + payer: paymentPayload.payload.voucher.buyer, + }; + } + if (balance < BigInt(paymentPayload.payload.voucher.valueAggregate)) { return { isValid: false, invalidReason: "insufficient_funds", @@ -169,17 +178,22 @@ export async function verify< } // Verify voucher id has not been already claimed + let isCollected: boolean; try { - const isCollected = await client.readContract({ + isCollected = await client.readContract({ address: paymentPayload.payload.voucher.escrow as Address, abi: deferredEscrowABI, functionName: "isCollected", args: [paymentPayload.payload.voucher.id as Hex], }); - if (isCollected) { - throw new Error(); - } } catch { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_contract_call_failed", + payer: paymentPayload.payload.voucher.buyer, + }; + } + if (isCollected) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_already_claimed", diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index b3032b27b0..0ca8ca3463 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -15,6 +15,7 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_recipient_mismatch", "invalid_deferred_evm_payload_asset_mismatch", "invalid_deferred_evm_payload_voucher_already_claimed", + "invalid_deferred_evm_payload_voucher_contract_call_failed", "invalid_deferred_evm_payload_signature", "invalid_deferred_evm_payload_no_longer_valid", ] as const; diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index 099318d236..5ae30896e0 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -20,7 +20,9 @@ import { EvmOrSvmAddress } from ".."; export const schemes = ["exact", "deferred"] as const; export const ErrorReasons = [ "insufficient_funds", + "insufficient_funds_contract_call_failed", "invalid_network", + "invalid_network_unsupported", "invalid_payload", "invalid_payment_requirements", "invalid_scheme", From 40e5ed865adbd72f1b850df7de53899d03b3656b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 17 Jul 2025 17:21:43 -0300 Subject: [PATCH 009/116] fix: when verifying check escrow balance not erc20 balance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/facilitator.ts | 17 ++++--- .../src/types/shared/evm/deferredEscrowABI.ts | 46 +++++++++++++++++++ 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 587a9ed3fa..8498d4f6e0 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -9,7 +9,6 @@ import { Transport, } from "viem"; import { getNetworkId } from "../../../shared"; -import { getERC20Balance } from "../../../shared/evm"; import { ConnectedClient, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, @@ -157,11 +156,17 @@ export async function verify< // Verify buyer has sufficient asset balance let balance: bigint; try { - balance = await getERC20Balance( - client, - paymentPayload.payload.voucher.asset as Address, - paymentPayload.payload.voucher.buyer as Address, - ); + const account = await client.readContract({ + address: paymentPayload.payload.voucher.escrow as Address, + abi: deferredEscrowABI, + functionName: "accounts", + args: [ + paymentPayload.payload.voucher.buyer as Address, + paymentPayload.payload.voucher.seller as Address, + paymentPayload.payload.voucher.asset as Address, + ], + }); + balance = account.balance; } catch { return { isValid: false, diff --git a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts index c30ceaa981..2c3a628ebd 100644 --- a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts +++ b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts @@ -30,4 +30,50 @@ export const deferredEscrowABI = [ ], outputs: [], }, + { + inputs: [ + { + internalType: "address", + name: "buyer", + type: "address", + }, + { + internalType: "address", + name: "seller", + type: "address", + }, + { + internalType: "address", + name: "asset", + type: "address", + }, + ], + name: "accounts", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "balance", + type: "uint256", + }, + { + internalType: "uint256", + name: "thawingAmount", + type: "uint256", + }, + { + internalType: "uint64", + name: "thawEndTime", + type: "uint64", + }, + ], + internalType: "struct IDeferredPaymentEscrow.EscrowAccount", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, ] as const; From 38a83fcc3205a3ae0e71de25a5e89dd8c9fab76b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 17 Jul 2025 17:39:13 -0300 Subject: [PATCH 010/116] chore: rename and move scheme name definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/client/createPaymentHeader.ts | 6 ++++-- .../x402/src/client/preparePaymentHeader.ts | 8 +++++--- .../x402/src/client/selectPaymentRequirements.ts | 9 +++++++-- .../packages/x402/src/client/signPaymentHeader.ts | 6 ++++-- .../packages/x402/src/facilitator/facilitator.ts | 13 ++++++------- .../x402/src/schemes/deferred/evm/client.ts | 3 ++- .../x402/src/schemes/deferred/evm/facilitator.ts | 11 ++++++++--- .../packages/x402/src/schemes/deferred/index.ts | 2 -- .../packages/x402/src/schemes/exact/evm/client.ts | 3 ++- .../x402/src/schemes/exact/evm/facilitator.ts | 5 ++--- .../packages/x402/src/schemes/exact/index.ts | 2 -- .../x402/src/types/verify/schemes/deferred.ts | 8 +++++--- .../x402/src/types/verify/schemes/exact.ts | 14 ++++++-------- .../packages/x402/src/types/verify/x402Specs.ts | 4 +++- 14 files changed, 54 insertions(+), 40 deletions(-) diff --git a/typescript/packages/x402/src/client/createPaymentHeader.ts b/typescript/packages/x402/src/client/createPaymentHeader.ts index 2eebbabc23..de963d4894 100644 --- a/typescript/packages/x402/src/client/createPaymentHeader.ts +++ b/typescript/packages/x402/src/client/createPaymentHeader.ts @@ -3,6 +3,8 @@ import { createPaymentHeader as createPaymentHeaderExactSVM } from "../schemes/e import { isEvmSignerWallet, isMultiNetworkSigner, isSvmSignerWallet, MultiNetworkSigner, Signer, SupportedEVMNetworks, SupportedSVMNetworks } from "../types/shared"; import { createPaymentHeader as createPaymentHeaderDeferredEVM } from "../schemes/deferred/evm/client"; import { PaymentRequirements } from "../types/verify"; +import { DEFERRRED_SCHEME } from "../types/verify/schemes/deferred"; +import { EXACT_SCHEME } from "../types/verify/schemes/exact"; /** * Creates a payment header based on the provided client and payment requirements. @@ -18,7 +20,7 @@ export async function createPaymentHeader( paymentRequirements: PaymentRequirements, ): Promise { // exact scheme - if (paymentRequirements.scheme === "exact") { + if (paymentRequirements.scheme === EXACT_SCHEME) { // evm if (SupportedEVMNetworks.includes(paymentRequirements.network)) { const evmClient = isMultiNetworkSigner(client) ? client.evm : client; @@ -51,7 +53,7 @@ export async function createPaymentHeader( // deferred scheme if ( - paymentRequirements.scheme === "deferred" && + paymentRequirements.scheme === DEFERRRED_SCHEME && SupportedEVMNetworks.includes(paymentRequirements.network) ) { return await createPaymentHeaderDeferredEVM(client, x402Version, paymentRequirements); diff --git a/typescript/packages/x402/src/client/preparePaymentHeader.ts b/typescript/packages/x402/src/client/preparePaymentHeader.ts index c168384ed9..7ba7c001e2 100644 --- a/typescript/packages/x402/src/client/preparePaymentHeader.ts +++ b/typescript/packages/x402/src/client/preparePaymentHeader.ts @@ -3,6 +3,8 @@ import { preparePaymentHeader as preparePaymentHeaderExactEVM } from "../schemes import { preparePaymentHeader as preparePaymentHeaderDeferredEVM } from "../schemes/deferred/evm/client"; import { SupportedEVMNetworks } from "../types/shared"; import { PaymentRequirements, UnsignedPaymentPayload } from "../types/verify"; +import { DEFERRRED_SCHEME } from "../types/verify/schemes/deferred"; +import { EXACT_SCHEME } from "../types/verify/schemes/exact"; /** * Prepares a payment header with the given sender address and payment requirements. @@ -19,7 +21,7 @@ export function preparePaymentHeader( paymentRequirements: PaymentRequirements, ): UnsignedPaymentPayload { if ( - paymentRequirements.scheme === "exact" && + paymentRequirements.scheme === EXACT_SCHEME && SupportedEVMNetworks.includes(paymentRequirements.network) ) { return preparePaymentHeaderExactEVM(from, x402Version, paymentRequirements); @@ -44,14 +46,14 @@ export function preparePaymentHeaderAsync( ): Promise { if ( - paymentRequirements.scheme === "exact" && + paymentRequirements.scheme === EXACT_SCHEME && SupportedEVMNetworks.includes(paymentRequirements.network) ) { return Promise.resolve(preparePaymentHeaderExactEVM(from, x402Version, paymentRequirements)); } if ( - paymentRequirements.scheme === "deferred" && + paymentRequirements.scheme === DEFERRRED_SCHEME && SupportedEVMNetworks.includes(paymentRequirements.network) ) { return preparePaymentHeaderDeferredEVM(from, x402Version, paymentRequirements); diff --git a/typescript/packages/x402/src/client/selectPaymentRequirements.ts b/typescript/packages/x402/src/client/selectPaymentRequirements.ts index 128654f005..1e06516afb 100644 --- a/typescript/packages/x402/src/client/selectPaymentRequirements.ts +++ b/typescript/packages/x402/src/client/selectPaymentRequirements.ts @@ -1,6 +1,7 @@ import { Network, PaymentRequirements } from "../types"; import { getUsdcChainConfigForChain } from "../shared/evm"; import { getNetworkId } from "../shared/network"; +import { EXACT_SCHEME } from "../types/verify/schemes/exact"; /** * Default selector for payment requirements. @@ -12,7 +13,11 @@ import { getNetworkId } from "../shared/network"; * @param scheme - The scheme to check against. If not provided, the scheme will not be checked. * @returns The payment requirement that is the most appropriate for the user. */ -export function selectPaymentRequirements(paymentRequirements: PaymentRequirements[], network?: Network | Network[], scheme?: "exact"): PaymentRequirements { +export function selectPaymentRequirements( + paymentRequirements: PaymentRequirements[], + network?: Network | Network[], + scheme?: typeof EXACT_SCHEME, +): PaymentRequirements { // Sort `base` payment requirements to the front of the list. This is to ensure that base is preferred if available. paymentRequirements.sort((a, b) => { if (a.network === "base" && b.network !== "base") { @@ -60,4 +65,4 @@ export function selectPaymentRequirements(paymentRequirements: PaymentRequiremen * @param scheme - The scheme to check against. If not provided, the scheme will not be checked. * @returns The payment requirement that is the most appropriate for the user. */ -export type PaymentRequirementsSelector = (paymentRequirements: PaymentRequirements[], network?: Network | Network[], scheme?: "exact") => PaymentRequirements; +export type PaymentRequirementsSelector = (paymentRequirements: PaymentRequirements[], network?: Network | Network[], scheme?: typeof EXACT_SCHEME) => PaymentRequirements; diff --git a/typescript/packages/x402/src/client/signPaymentHeader.ts b/typescript/packages/x402/src/client/signPaymentHeader.ts index 783f590723..50828d5f07 100644 --- a/typescript/packages/x402/src/client/signPaymentHeader.ts +++ b/typescript/packages/x402/src/client/signPaymentHeader.ts @@ -6,6 +6,8 @@ import { encodePayment as encodePaymentDeferredEVM } from "../schemes/deferred/e import { PaymentRequirements, UnsignedPaymentPayload } from "../types/verify"; import { UnsignedDeferredPaymentPayloadSchema } from "../types/verify/schemes/deferred"; import { UnsignedExactPaymentPayloadSchema } from "../types/verify/schemes/exact"; +import { DEFERRRED_SCHEME } from "../types/verify/schemes/deferred"; +import { EXACT_SCHEME } from "../types/verify/schemes/exact"; /** * Signs a payment header using the provided client and payment requirements. @@ -21,7 +23,7 @@ export async function signPaymentHeader( unsignedPaymentHeader: UnsignedPaymentPayload, ): Promise { if ( - paymentRequirements.scheme === "exact" && + paymentRequirements.scheme === EXACT_SCHEME && SupportedEVMNetworks.includes(paymentRequirements.network) ) { const evmClient = isMultiNetworkSigner(client) ? client.evm : client; @@ -35,7 +37,7 @@ export async function signPaymentHeader( } if ( - paymentRequirements.scheme === "deferred" && + paymentRequirements.scheme === DEFERRRED_SCHEME && SupportedEVMNetworks.includes(paymentRequirements.network) ) { unsignedPaymentHeader = UnsignedDeferredPaymentPayloadSchema.parse(unsignedPaymentHeader); diff --git a/typescript/packages/x402/src/facilitator/facilitator.ts b/typescript/packages/x402/src/facilitator/facilitator.ts index c61e6ad06b..a7aa7d1c25 100644 --- a/typescript/packages/x402/src/facilitator/facilitator.ts +++ b/typescript/packages/x402/src/facilitator/facilitator.ts @@ -18,6 +18,8 @@ import { Chain, Transport, Account } from "viem"; import { KeyPairSigner } from "@solana/kit"; import { ExactPaymentPayloadSchema } from "../types/verify/schemes/exact"; import { DeferredPaymentPayloadSchema } from "../types/verify/schemes/deferred"; +import { DEFERRRED_SCHEME } from "../types/verify/schemes/deferred"; +import { EXACT_SCHEME } from "../types/verify/schemes/exact"; /** * Verifies a payment payload against the required payment details regardless of the scheme @@ -37,8 +39,7 @@ export async function verify< payload: PaymentPayload, paymentRequirements: PaymentRequirements, ): Promise { - // exact scheme - if (paymentRequirements.scheme === "exact") { + if (paymentRequirements.scheme == EXACT_SCHEME) { payload = ExactPaymentPayloadSchema.parse(payload); // evm if (SupportedEVMNetworks.includes(paymentRequirements.network)) { @@ -55,8 +56,7 @@ export async function verify< } } - // deferred scheme - if (paymentRequirements.scheme == "deferred") { + if (paymentRequirements.scheme == DEFERRRED_SCHEME) { payload = DeferredPaymentPayloadSchema.parse(payload); if (SupportedEVMNetworks.includes(paymentRequirements.network)) { const valid = await verifyDeferred(client, payload, paymentRequirements); @@ -94,8 +94,7 @@ export async function settle( payload: PaymentPayload, paymentRequirements: PaymentRequirements, ): Promise { - // exact scheme - if (paymentRequirements.scheme === "exact") { + if (paymentRequirements.scheme == EXACT_SCHEME) { payload = ExactPaymentPayloadSchema.parse(payload); // evm if (SupportedEVMNetworks.includes(paymentRequirements.network)) { @@ -112,7 +111,7 @@ export async function settle( } } - if (paymentRequirements.scheme == "deferred") { + if (paymentRequirements.scheme == DEFERRRED_SCHEME) { payload = DeferredPaymentPayloadSchema.parse(payload); if (SupportedEVMNetworks.includes(paymentRequirements.network)) { return settleDeferred(client, payload, paymentRequirements); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index b90cddbe38..e031934eb3 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -11,6 +11,7 @@ import { UnsignedDeferredPaymentPayloadSchema, } from "../../../types/verify/schemes/deferred"; import { getNetworkId } from "../../../shared/network"; +import { DEFERRRED_SCHEME } from "../../../types/verify/schemes/deferred"; /** * Prepares an unsigned payment header with the given sender address and payment requirements. @@ -34,7 +35,7 @@ export async function preparePaymentHeader( return { x402Version, - scheme: "deferred", + scheme: DEFERRRED_SCHEME, network: deferredPaymentRequirements.network, payload: { signature: undefined, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 8498d4f6e0..517805ffbc 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -16,8 +16,10 @@ import { SettleResponse, VerifyResponse, } from "../../../types/verify"; -import { SCHEME } from "../../deferred"; -import { DeferredPaymentPayloadSchema } from "../../../types/verify/schemes/deferred"; +import { + DeferredPaymentPayloadSchema, + DEFERRRED_SCHEME, +} from "../../../types/verify/schemes/deferred"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; import { verifyVoucher } from "./sign"; @@ -54,7 +56,10 @@ export async function verify< paymentPayload = DeferredPaymentPayloadSchema.parse(paymentPayload); // Verify payload matches requirements: scheme - if (paymentPayload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) { + if ( + paymentPayload.scheme !== DEFERRRED_SCHEME || + paymentRequirements.scheme !== DEFERRRED_SCHEME + ) { return { isValid: false, invalidReason: `unsupported_scheme`, diff --git a/typescript/packages/x402/src/schemes/deferred/index.ts b/typescript/packages/x402/src/schemes/deferred/index.ts index f1753e0f1d..5bd1dde8df 100644 --- a/typescript/packages/x402/src/schemes/deferred/index.ts +++ b/typescript/packages/x402/src/schemes/deferred/index.ts @@ -1,3 +1 @@ export * as evm from "./evm"; - -export const SCHEME = "deferred"; diff --git a/typescript/packages/x402/src/schemes/exact/evm/client.ts b/typescript/packages/x402/src/schemes/exact/evm/client.ts index d5dbd9825e..cd19554232 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/client.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/client.ts @@ -7,6 +7,7 @@ import { ExactPaymentPayload, UnsignedExactPaymentPayload, } from "../../../types/verify/schemes/exact"; +import { EXACT_SCHEME } from "../../../types/verify/schemes/exact"; /** * Prepares an unsigned payment header with the given sender address and payment requirements. @@ -32,7 +33,7 @@ export function preparePaymentHeader( return { x402Version, - scheme: "exact", + scheme: EXACT_SCHEME, network: paymentRequirements.network, payload: { signature: undefined, diff --git a/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts b/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts index f455dd5d2d..6bf59c5ec4 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts @@ -15,8 +15,7 @@ import { VerifyResponse, ExactEvmPayload, } from "../../../types/verify"; -import { SCHEME } from "../../exact"; -import { ExactPaymentPayload } from "../../../types/verify/schemes/exact"; +import { ExactPaymentPayload, EXACT_SCHEME } from "../../../types/verify/schemes/exact"; /** * Verifies a payment payload against the required payment details @@ -59,7 +58,7 @@ export async function verify< const exactEvmPayload = payload.payload as ExactEvmPayload; // Verify payload version - if (payload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) { + if (payload.scheme !== EXACT_SCHEME || paymentRequirements.scheme !== EXACT_SCHEME) { return { isValid: false, invalidReason: `unsupported_scheme`, diff --git a/typescript/packages/x402/src/schemes/exact/index.ts b/typescript/packages/x402/src/schemes/exact/index.ts index c4ecc8e84b..4ab33771eb 100644 --- a/typescript/packages/x402/src/schemes/exact/index.ts +++ b/typescript/packages/x402/src/schemes/exact/index.ts @@ -1,4 +1,2 @@ export * as evm from "./evm"; export * as svm from "./svm"; - -export const SCHEME = "exact"; diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 0ca8ca3463..ae5363e27f 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -8,6 +8,8 @@ import { import { hasMaxLength, isInteger } from "../refiners"; import { BasePaymentPayloadSchema, BasePaymentRequirementsSchema } from "./base"; +export const DEFERRRED_SCHEME = "deferred"; + export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_network_mismatch", "invalid_deferred_evm_payload_chain_id", @@ -43,14 +45,14 @@ export type DeferredEvmPayload = z.infer; // x402DeferredPaymentPayload export const DeferredPaymentPayloadSchema = BasePaymentPayloadSchema.extend({ - scheme: z.literal("deferred"), + scheme: z.literal(DEFERRRED_SCHEME), payload: DeferredEvmPayloadSchema, }); export type DeferredPaymentPayload = z.infer; // x402UnsignedDeferredPaymentPayload export const UnsignedDeferredPaymentPayloadSchema = BasePaymentPayloadSchema.extend({ - scheme: z.literal("deferred"), + scheme: z.literal(DEFERRRED_SCHEME), payload: DeferredEvmPayloadSchema.omit({ signature: true }).extend({ signature: z.undefined(), }), @@ -78,7 +80,7 @@ export type DeferredEvmPaymentRequirementsExtraAggregationVoucher = z.infer< // x402DeferredPaymentRequirements export const DeferredPaymentRequirementsSchema = BasePaymentRequirementsSchema.extend({ - scheme: z.literal("deferred"), + scheme: z.literal(DEFERRRED_SCHEME), extra: z.discriminatedUnion("type", [ DeferredEvmPaymentRequirementsExtraNewVoucherSchema, DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, diff --git a/typescript/packages/x402/src/types/verify/schemes/exact.ts b/typescript/packages/x402/src/types/verify/schemes/exact.ts index e77a53b8fa..fdb18d7de2 100644 --- a/typescript/packages/x402/src/types/verify/schemes/exact.ts +++ b/typescript/packages/x402/src/types/verify/schemes/exact.ts @@ -7,10 +7,10 @@ import { } from "../constants"; import { hasMaxLength, isInteger } from "../refiners"; import { Base64EncodedRegex } from "../../../shared"; -import { NetworkSchema } from "../../shared"; -import { x402Versions } from "../versions"; import { BasePaymentPayloadSchema, BasePaymentRequirementsSchema } from "./base"; +export const EXACT_SCHEME = "exact"; + export const ExactErrorReasons = [ "invalid_exact_evm_payload_authorization_valid_after", "invalid_exact_evm_payload_authorization_valid_before", @@ -70,17 +70,15 @@ export const ExactSvmPayloadSchema = z.object({ export type ExactSvmPayload = z.infer; // x402ExactPaymentPayload -export const ExactPaymentPayloadSchema = z.object({ - x402Version: z.number().refine(val => x402Versions.includes(val as 1)), - scheme: z.literal("exact"), - network: NetworkSchema, +export const ExactPaymentPayloadSchema = BasePaymentPayloadSchema.extend({ + scheme: z.literal(EXACT_SCHEME), payload: z.union([ExactEvmPayloadSchema, ExactSvmPayloadSchema]), }); export type ExactPaymentPayload = z.infer; // x402UnsignedPaymentPayload export const UnsignedExactPaymentPayloadSchema = BasePaymentPayloadSchema.extend({ - scheme: z.literal("exact"), + scheme: z.literal(EXACT_SCHEME), payload: ExactEvmPayloadSchema.omit({ signature: true }).extend({ signature: z.undefined(), }), @@ -89,7 +87,7 @@ export type UnsignedExactPaymentPayload = z.infer Date: Thu, 17 Jul 2025 17:45:05 -0300 Subject: [PATCH 011/116] fix: clearer verification invalid reasons for deferred scheme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/facilitator.ts | 22 +++++++++++++------ .../x402/src/types/verify/schemes/deferred.ts | 3 +++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 517805ffbc..ea19801c19 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -56,14 +56,22 @@ export async function verify< paymentPayload = DeferredPaymentPayloadSchema.parse(paymentPayload); // Verify payload matches requirements: scheme - if ( - paymentPayload.scheme !== DEFERRRED_SCHEME || - paymentRequirements.scheme !== DEFERRRED_SCHEME - ) { + if (paymentPayload.scheme !== DEFERRRED_SCHEME) { return { isValid: false, - invalidReason: `unsupported_scheme`, - payer: paymentPayload.payload.voucher.buyer, + invalidReason: `invalid_deferred_evm_payload_scheme`, + }; + } + if (paymentRequirements.scheme !== DEFERRRED_SCHEME) { + return { + isValid: false, + invalidReason: `invalid_deferred_evm_requirements_scheme`, + }; + } + if (paymentPayload.scheme !== paymentRequirements.scheme) { + return { + isValid: false, + invalidReason: `invalid_deferred_evm_payload_requirements_scheme_mismatch`, }; } @@ -71,7 +79,7 @@ export async function verify< if (paymentPayload.network !== paymentRequirements.network) { return { isValid: false, - invalidReason: `invalid_network`, + invalidReason: `invalid_deferred_evm_payload_network_mismatch`, payer: paymentPayload.payload.voucher.buyer, }; } diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index ae5363e27f..b47a8a7fe3 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -11,6 +11,9 @@ import { BasePaymentPayloadSchema, BasePaymentRequirementsSchema } from "./base" export const DEFERRRED_SCHEME = "deferred"; export const DeferredErrorReasons = [ + "invalid_deferred_evm_payload_scheme", + "invalid_deferred_evm_requirements_scheme", + "invalid_deferred_evm_payload_requirements_scheme_mismatch", "invalid_deferred_evm_payload_network_mismatch", "invalid_deferred_evm_payload_chain_id", "invalid_deferred_evm_payload_voucher_value", From 103af8113574a12a74d68a5922b607a6039150b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 17 Jul 2025 17:46:57 -0300 Subject: [PATCH 012/116] chore: add TODO comment about simulating tx on verify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index ea19801c19..8b1e949eb9 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -37,6 +37,7 @@ import { verifyVoucher } from "./sign"; * - ✅ Validates the voucher chainId matches the chain specified in the payment requirements * - ✅ (on-chain) Verifies buyer has sufficient asset balance * - ✅ (on-chain) Verifies the voucher id has not been already claimed + * - ⌛ TODO: Simulate the transaction to ensure it will succeed * * @param client - The public client used for blockchain interactions * @param paymentPayload - The signed payment payload containing transfer parameters and signature From 8527fdc63d8d37511a9b13d8e2f0aac01b87796d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 17 Jul 2025 17:49:26 -0300 Subject: [PATCH 013/116] chore: ensure consistent usage of buyer over from in deferred scheme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/schemes/deferred/evm/client.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index e031934eb3..c619a0e844 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -16,13 +16,13 @@ import { DEFERRRED_SCHEME } from "../../../types/verify/schemes/deferred"; /** * 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 buyer - 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 */ export async function preparePaymentHeader( - from: Address, + buyer: Address, x402Version: number, paymentRequirements: PaymentRequirements, ): Promise { @@ -30,8 +30,8 @@ export async function preparePaymentHeader( const voucher = deferredPaymentRequirements.extra.type === "new" - ? createNewVoucher(from, deferredPaymentRequirements) - : await aggregateVoucher(from, deferredPaymentRequirements); + ? createNewVoucher(buyer, deferredPaymentRequirements) + : await aggregateVoucher(buyer, deferredPaymentRequirements); return { x402Version, @@ -47,12 +47,12 @@ export async function preparePaymentHeader( /** * Creates a new voucher with the given payment requirements * - * @param from - The sender's address from which the payment will be made + * @param buyer - The sender's address from which the payment will be made * @param paymentRequirements - The payment requirements containing scheme and network information * @returns The new voucher */ export function createNewVoucher( - from: Address, + buyer: Address, paymentRequirements: PaymentRequirements, ): DeferredEvmPayloadVoucher { const extra = DeferredEvmPaymentRequirementsExtraNewVoucherSchema.parse( @@ -61,7 +61,7 @@ export function createNewVoucher( return { id: extra.voucher.id, - buyer: from, + buyer: buyer, seller: paymentRequirements.payTo, valueAggregate: paymentRequirements.maxAmountRequired, asset: paymentRequirements.asset, @@ -75,12 +75,12 @@ export function createNewVoucher( /** * Aggregates a voucher with new payment requirements * - * @param from - The sender's address from which the payment will be made + * @param buyer - The sender's address from which the payment will be made * @param paymentRequirements - The payment requirements containing scheme and network information * @returns The aggregated voucher */ export async function aggregateVoucher( - from: Address, + buyer: Address, paymentRequirements: PaymentRequirements, ): Promise { const extra = DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema.parse( @@ -88,12 +88,12 @@ export async function aggregateVoucher( ); // verify signature is valid and the voucher's buyer is the client - const isValid = await verifyVoucher(extra.voucher, extra.signature as Hex, from); + const isValid = await verifyVoucher(extra.voucher, extra.signature as Hex, buyer); if (!isValid) { throw new Error("Invalid voucher signature"); } - const { id, escrow, buyer, seller, valueAggregate, asset, nonce, chainId } = extra.voucher; + const { id, escrow, seller, valueAggregate, asset, nonce, chainId } = extra.voucher; const newTimestamp = Math.floor(Date.now() / 1000); return { From 60d2f16447624376e495a29730b23202a7e90fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 17 Jul 2025 17:56:41 -0300 Subject: [PATCH 014/116] fix: more clear reject reason for verify fn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/facilitator/facilitator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript/packages/x402/src/facilitator/facilitator.ts b/typescript/packages/x402/src/facilitator/facilitator.ts index a7aa7d1c25..97082d9720 100644 --- a/typescript/packages/x402/src/facilitator/facilitator.ts +++ b/typescript/packages/x402/src/facilitator/facilitator.ts @@ -64,7 +64,7 @@ export async function verify< } else { return { isValid: false, - invalidReason: "invalid_scheme", + invalidReason: "invalid_network", payer: payload.payload.voucher.buyer, }; } From 14f9363ecd1a2aa28d67c8c8a8e140a543e501e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 17 Jul 2025 17:58:20 -0300 Subject: [PATCH 015/116] chore: rename voucher verification function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../packages/x402/src/schemes/deferred/evm/client.ts | 4 ++-- .../x402/src/schemes/deferred/evm/facilitator.ts | 4 ++-- .../x402/src/schemes/deferred/evm/sign.test.ts | 10 +++++++--- .../packages/x402/src/schemes/deferred/evm/sign.ts | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index c619a0e844..f4c7fecc96 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -1,7 +1,7 @@ import { Address, Chain, Hex, LocalAccount, Transport } from "viem"; import { isSignerWallet, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, PaymentRequirements, UnsignedPaymentPayload } from "../../../types/verify"; -import { signVoucher, verifyVoucher } from "./sign"; +import { signVoucher, verifyVoucherSignature } from "./sign"; import { encodePayment } from "./utils/paymentUtils"; import { DeferredEvmPayloadVoucher, @@ -88,7 +88,7 @@ export async function aggregateVoucher( ); // verify signature is valid and the voucher's buyer is the client - const isValid = await verifyVoucher(extra.voucher, extra.signature as Hex, buyer); + const isValid = await verifyVoucherSignature(extra.voucher, extra.signature as Hex, buyer); if (!isValid) { throw new Error("Invalid voucher signature"); } diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 8b1e949eb9..d26fbca33f 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -21,7 +21,7 @@ import { DEFERRRED_SCHEME, } from "../../../types/verify/schemes/deferred"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; -import { verifyVoucher } from "./sign"; +import { verifyVoucherSignature } from "./sign"; /** * Verifies a payment payload against the required payment details @@ -154,7 +154,7 @@ export async function verify< } // Verify voucher signature is recoverable for the owner address - const voucherSignatureIsValid = await verifyVoucher( + const voucherSignatureIsValid = await verifyVoucherSignature( paymentPayload.payload.voucher, paymentPayload.payload.signature as Hex, paymentPayload.payload.voucher.buyer as Address, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts index b5ad80fe8b..89d3bb9667 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createSigner } from "../../../types/shared/evm"; -import { signVoucher, verifyVoucher } from "./sign"; +import { signVoucher, verifyVoucherSignature } from "./sign"; const buyer = createSigner( "base-sepolia", @@ -46,12 +46,16 @@ describe("voucher signature", () => { }); it("should verify a valid voucher signature", async () => { - const isValid = await verifyVoucher(mockVoucher, mockVoucherSignature, buyerAddress); + const isValid = await verifyVoucherSignature(mockVoucher, mockVoucherSignature, buyerAddress); expect(isValid).toBe(true); }); it("should return false if voucher signature is valid but for a different buyer", async () => { - const isValid = await verifyVoucher(mockVoucher, mockVoucherSignature, anotherBuyerAddress); + const isValid = await verifyVoucherSignature( + mockVoucher, + mockVoucherSignature, + anotherBuyerAddress, + ); expect(isValid).toBe(false); }); }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts index 6777341b9b..9f019a8528 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts @@ -65,7 +65,7 @@ export async function signVoucher Date: Fri, 18 Jul 2025 10:40:14 -0300 Subject: [PATCH 016/116] feat: verify client network matches voucher network MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/schemes/deferred/evm/facilitator.ts | 10 ++++++++++ typescript/packages/x402/src/types/verify/x402Specs.ts | 1 + 2 files changed, 11 insertions(+) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index d26fbca33f..108b4788c5 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -35,6 +35,7 @@ import { verifyVoucherSignature } from "./sign"; * - ✅ Verify voucher asset matches payment requirements * - ✅ Validates the signature is valid * - ✅ Validates the voucher chainId matches the chain specified in the payment requirements + * - ✅ (on-chain) Verifies the client is connected to the chain specified in the payment requirements * - ✅ (on-chain) Verifies buyer has sufficient asset balance * - ✅ (on-chain) Verifies the voucher id has not been already claimed * - ⌛ TODO: Simulate the transaction to ensure it will succeed @@ -167,6 +168,15 @@ export async function verify< }; } + // Verify the client is connected to the chain specified in the payment requirements + if (client.chain.id !== chainId) { + return { + isValid: false, + invalidReason: "invalid_client_network", + payer: paymentPayload.payload.voucher.buyer, + }; + } + // Verify buyer has sufficient asset balance let balance: bigint; try { diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index ec0178def5..2375fa35b4 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -25,6 +25,7 @@ export const ErrorReasons = [ "insufficient_funds_contract_call_failed", "invalid_network", "invalid_network_unsupported", + "invalid_client_network", "invalid_payload", "invalid_payment_requirements", "invalid_scheme", From 3314e577c1f0d458f08e3d225b549234fa8403ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 18 Jul 2025 10:42:39 -0300 Subject: [PATCH 017/116] fix: remove unreachable code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../packages/x402/src/schemes/deferred/evm/facilitator.ts | 6 ------ .../packages/x402/src/types/verify/schemes/deferred.ts | 1 - 2 files changed, 7 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 108b4788c5..640e719f1f 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -70,12 +70,6 @@ export async function verify< invalidReason: `invalid_deferred_evm_requirements_scheme`, }; } - if (paymentPayload.scheme !== paymentRequirements.scheme) { - return { - isValid: false, - invalidReason: `invalid_deferred_evm_payload_requirements_scheme_mismatch`, - }; - } // Verify payload matches requirements: network if (paymentPayload.network !== paymentRequirements.network) { diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index b47a8a7fe3..cbd8752d04 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -13,7 +13,6 @@ export const DEFERRRED_SCHEME = "deferred"; export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_scheme", "invalid_deferred_evm_requirements_scheme", - "invalid_deferred_evm_payload_requirements_scheme_mismatch", "invalid_deferred_evm_payload_network_mismatch", "invalid_deferred_evm_payload_chain_id", "invalid_deferred_evm_payload_voucher_value", From d6eb04d3123c45fc284cc3316443905eccda7108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 18 Jul 2025 10:43:23 -0300 Subject: [PATCH 018/116] chore: comment clarification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../packages/x402/src/schemes/deferred/evm/facilitator.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 640e719f1f..0a6c6dd0b8 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -101,7 +101,7 @@ export async function verify< if ( BigInt(paymentPayload.payload.voucher.valueAggregate) < BigInt(paymentRequirements.maxAmountRequired) + - BigInt(paymentRequirements.extra.voucher.valueAggregate) + BigInt(paymentRequirements.extra.voucher.valueAggregate) ) { return { isValid: false, @@ -171,7 +171,7 @@ export async function verify< }; } - // Verify buyer has sufficient asset balance + // Verify buyer has sufficient asset balance in the escrow contract let balance: bigint; try { const account = await client.readContract({ From cbaba301a21fc0640f03e35a3d6d13d823e8c491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 18 Jul 2025 11:30:34 -0300 Subject: [PATCH 019/116] fix: clean up verification code, ensure client verifies aggregate voucher payment requirements match MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/schemes/deferred/evm/client.ts | 19 +- .../src/schemes/deferred/evm/facilitator.ts | 204 +-------------- .../src/schemes/deferred/evm/sign.test.ts | 10 +- .../x402/src/schemes/deferred/evm/sign.ts | 2 +- .../x402/src/schemes/deferred/evm/verify.ts | 237 ++++++++++++++++++ 5 files changed, 267 insertions(+), 205 deletions(-) create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/verify.ts diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index f4c7fecc96..2292ad360d 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -1,7 +1,7 @@ import { Address, Chain, Hex, LocalAccount, Transport } from "viem"; import { isSignerWallet, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, PaymentRequirements, UnsignedPaymentPayload } from "../../../types/verify"; -import { signVoucher, verifyVoucherSignature } from "./sign"; +import { signVoucher, verifyVoucher } from "./sign"; import { encodePayment } from "./utils/paymentUtils"; import { DeferredEvmPayloadVoucher, @@ -86,15 +86,24 @@ export async function aggregateVoucher( const extra = DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema.parse( paymentRequirements.extra, ); + const { id, escrow, seller, valueAggregate, asset, nonce, chainId } = extra.voucher; // verify signature is valid and the voucher's buyer is the client - const isValid = await verifyVoucherSignature(extra.voucher, extra.signature as Hex, buyer); + const isValid = await verifyVoucher(extra.voucher, extra.signature as Hex, buyer); if (!isValid) { throw new Error("Invalid voucher signature"); } - const { id, escrow, seller, valueAggregate, asset, nonce, chainId } = extra.voucher; - const newTimestamp = Math.floor(Date.now() / 1000); + // verify previous voucher matches payment requirements + if (paymentRequirements.payTo !== seller) { + throw new Error("Invalid voucher seller"); + } + if (paymentRequirements.asset !== asset) { + throw new Error("Invalid voucher asset"); + } + if (getNetworkId(paymentRequirements.network) !== chainId) { + throw new Error("Invalid voucher chainId"); + } return { id, @@ -104,7 +113,7 @@ export async function aggregateVoucher( BigInt(paymentRequirements.maxAmountRequired) + BigInt(valueAggregate) ).toString(), asset, - timestamp: newTimestamp, + timestamp: Math.floor(Date.now() / 1000), nonce: nonce + 1, escrow, chainId, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 0a6c6dd0b8..8693e6ce4c 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -1,14 +1,4 @@ -import { - Account, - Address, - Chain, - getAddress, - Hex, - encodeAbiParameters, - parseAbiParameters, - Transport, -} from "viem"; -import { getNetworkId } from "../../../shared"; +import { Account, Address, Chain, encodeAbiParameters, parseAbiParameters, Transport } from "viem"; import { ConnectedClient, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, @@ -16,29 +6,17 @@ import { SettleResponse, VerifyResponse, } from "../../../types/verify"; -import { - DeferredPaymentPayloadSchema, - DEFERRRED_SCHEME, -} from "../../../types/verify/schemes/deferred"; +import { DeferredPaymentPayloadSchema } from "../../../types/verify/schemes/deferred"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; -import { verifyVoucherSignature } from "./sign"; +import { verifyPaymentRequirements, verifyVoucherSignature, verifyOnchainState } from "./verify"; /** * Verifies a payment payload against the required payment details * * This function performs several verification steps: - * - ✅ Verify payload matches requirements - * - ✅ Verify scheme is deferred - * - ✅ Verify network matches payment requirements - * - ✅ Verify voucher value is enough to cover maxAmountRequired - * - ✅ Verify payTo is voucher seller - * - ✅ Verify voucher asset matches payment requirements - * - ✅ Validates the signature is valid - * - ✅ Validates the voucher chainId matches the chain specified in the payment requirements - * - ✅ (on-chain) Verifies the client is connected to the chain specified in the payment requirements - * - ✅ (on-chain) Verifies buyer has sufficient asset balance - * - ✅ (on-chain) Verifies the voucher id has not been already claimed - * - ⌛ TODO: Simulate the transaction to ensure it will succeed + * - ✅ Validates the payment payload matches the payment requirements + * - ✅ Validates the voucher signature is valid + * - ✅ Validates the onchain state allows the payment to be settled * * @param client - The public client used for blockchain interactions * @param paymentPayload - The signed payment payload containing transfer parameters and signature @@ -57,172 +35,14 @@ export async function verify< // Verify payload is a deferred payment payload - plus type assert to DeferredPaymentPayload paymentPayload = DeferredPaymentPayloadSchema.parse(paymentPayload); - // Verify payload matches requirements: scheme - if (paymentPayload.scheme !== DEFERRRED_SCHEME) { - return { - isValid: false, - invalidReason: `invalid_deferred_evm_payload_scheme`, - }; - } - if (paymentRequirements.scheme !== DEFERRRED_SCHEME) { - return { - isValid: false, - invalidReason: `invalid_deferred_evm_requirements_scheme`, - }; - } - - // Verify payload matches requirements: network - if (paymentPayload.network !== paymentRequirements.network) { - return { - isValid: false, - invalidReason: `invalid_deferred_evm_payload_network_mismatch`, - payer: paymentPayload.payload.voucher.buyer, - }; - } - - // Verify payload matches requirements: maxAmountRequired -- new vouchers - // value in voucher should be enough to cover paymentRequirements.maxAmountRequired - if (paymentRequirements.extra.type === "new") { - if ( - BigInt(paymentPayload.payload.voucher.valueAggregate) < - BigInt(paymentRequirements.maxAmountRequired) - ) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_value", - payer: paymentPayload.payload.voucher.buyer, - }; - } - } - - // Verify payload matches requirements: maxAmountRequired -- aggregate vouchers - // value in voucher should be enough to cover paymentRequirements.maxAmountRequired plus previous voucher value - if (paymentRequirements.extra.type === "aggregation") { - if ( - BigInt(paymentPayload.payload.voucher.valueAggregate) < - BigInt(paymentRequirements.maxAmountRequired) + - BigInt(paymentRequirements.extra.voucher.valueAggregate) - ) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_value", - payer: paymentPayload.payload.voucher.buyer, - }; - } - } - - // Verify payload matches requirements: payTo - if (getAddress(paymentPayload.payload.voucher.seller) !== getAddress(paymentRequirements.payTo)) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_recipient_mismatch", - payer: paymentPayload.payload.voucher.buyer, - }; - } + // Verify the payment payload matches the payment requirements + await verifyPaymentRequirements(paymentPayload, paymentRequirements); - // Verify payload matches requirements: asset - if (paymentPayload.payload.voucher.asset !== paymentRequirements.asset) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_asset_mismatch", - payer: paymentPayload.payload.voucher.buyer, - }; - } + // Verify voucher signature is valid + await verifyVoucherSignature(paymentPayload); - //Validates the voucher chainId matches the chain specified in the payment requirements - let chainId: number; - try { - chainId = getNetworkId(paymentRequirements.network); - } catch { - return { - isValid: false, - invalidReason: `invalid_network_unsupported`, - payer: paymentPayload.payload.voucher.buyer, - }; - } - if (chainId !== paymentPayload.payload.voucher.chainId) { - return { - isValid: false, - invalidReason: `invalid_deferred_evm_payload_chain_id`, - payer: paymentPayload.payload.voucher.buyer, - }; - } - - // Verify voucher signature is recoverable for the owner address - const voucherSignatureIsValid = await verifyVoucherSignature( - paymentPayload.payload.voucher, - paymentPayload.payload.signature as Hex, - paymentPayload.payload.voucher.buyer as Address, - ); - if (!voucherSignatureIsValid) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_signature", - payer: paymentPayload.payload.voucher.buyer, - }; - } - - // Verify the client is connected to the chain specified in the payment requirements - if (client.chain.id !== chainId) { - return { - isValid: false, - invalidReason: "invalid_client_network", - payer: paymentPayload.payload.voucher.buyer, - }; - } - - // Verify buyer has sufficient asset balance in the escrow contract - let balance: bigint; - try { - const account = await client.readContract({ - address: paymentPayload.payload.voucher.escrow as Address, - abi: deferredEscrowABI, - functionName: "accounts", - args: [ - paymentPayload.payload.voucher.buyer as Address, - paymentPayload.payload.voucher.seller as Address, - paymentPayload.payload.voucher.asset as Address, - ], - }); - balance = account.balance; - } catch { - return { - isValid: false, - invalidReason: "insufficient_funds_contract_call_failed", - payer: paymentPayload.payload.voucher.buyer, - }; - } - if (balance < BigInt(paymentPayload.payload.voucher.valueAggregate)) { - return { - isValid: false, - invalidReason: "insufficient_funds", - payer: paymentPayload.payload.voucher.buyer, - }; - } - - // Verify voucher id has not been already claimed - let isCollected: boolean; - try { - isCollected = await client.readContract({ - address: paymentPayload.payload.voucher.escrow as Address, - abi: deferredEscrowABI, - functionName: "isCollected", - args: [paymentPayload.payload.voucher.id as Hex], - }); - } catch { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_contract_call_failed", - payer: paymentPayload.payload.voucher.buyer, - }; - } - if (isCollected) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_already_claimed", - payer: paymentPayload.payload.voucher.buyer, - }; - } + // Verify the onchain state allows the payment to be settled + await verifyOnchainState(client, paymentPayload, paymentRequirements); return { isValid: true, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts index 89d3bb9667..b5ad80fe8b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createSigner } from "../../../types/shared/evm"; -import { signVoucher, verifyVoucherSignature } from "./sign"; +import { signVoucher, verifyVoucher } from "./sign"; const buyer = createSigner( "base-sepolia", @@ -46,16 +46,12 @@ describe("voucher signature", () => { }); it("should verify a valid voucher signature", async () => { - const isValid = await verifyVoucherSignature(mockVoucher, mockVoucherSignature, buyerAddress); + const isValid = await verifyVoucher(mockVoucher, mockVoucherSignature, buyerAddress); expect(isValid).toBe(true); }); it("should return false if voucher signature is valid but for a different buyer", async () => { - const isValid = await verifyVoucherSignature( - mockVoucher, - mockVoucherSignature, - anotherBuyerAddress, - ); + const isValid = await verifyVoucher(mockVoucher, mockVoucherSignature, anotherBuyerAddress); expect(isValid).toBe(false); }); }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts index 9f019a8528..6777341b9b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts @@ -65,7 +65,7 @@ export async function signVoucher( + client: ConnectedClient, + paymentPayload: DeferredPaymentPayload, + paymentRequirements: PaymentRequirements, +) { + let chainId: number; + try { + chainId = getNetworkId(paymentRequirements.network); + } catch { + return { + isValid: false, + invalidReason: `invalid_network_unsupported`, + payer: paymentPayload.payload.voucher.buyer, + }; + } + + // Verify the client is connected to the chain specified in the payment requirements + if (client.chain.id !== chainId) { + return { + isValid: false, + invalidReason: "invalid_client_network", + payer: paymentPayload.payload.voucher.buyer, + }; + } + + // Verify buyer has sufficient asset balance in the escrow contract + let balance: bigint; + try { + const account = await client.readContract({ + address: paymentPayload.payload.voucher.escrow as Address, + abi: deferredEscrowABI, + functionName: "accounts", + args: [ + paymentPayload.payload.voucher.buyer as Address, + paymentPayload.payload.voucher.seller as Address, + paymentPayload.payload.voucher.asset as Address, + ], + }); + balance = account.balance; + } catch { + return { + isValid: false, + invalidReason: "insufficient_funds_contract_call_failed", + payer: paymentPayload.payload.voucher.buyer, + }; + } + if (balance < BigInt(paymentPayload.payload.voucher.valueAggregate)) { + return { + isValid: false, + invalidReason: "insufficient_funds", + payer: paymentPayload.payload.voucher.buyer, + }; + } + + // Verify voucher id has not been already claimed + let isCollected: boolean; + try { + isCollected = await client.readContract({ + address: paymentPayload.payload.voucher.escrow as Address, + abi: deferredEscrowABI, + functionName: "isCollected", + args: [paymentPayload.payload.voucher.id as Hex], + }); + } catch { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_contract_call_failed", + payer: paymentPayload.payload.voucher.buyer, + }; + } + if (isCollected) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_already_claimed", + payer: paymentPayload.payload.voucher.buyer, + }; + } +} From 51566f4047717f180e78fd40fb9caf451eda0ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 18 Jul 2025 11:58:25 -0300 Subject: [PATCH 020/116] test: add tests for verification steps on deferred scheme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/verify.test.ts | 452 ++++++++++++++++++ 1 file changed, 452 insertions(+) create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts new file mode 100644 index 0000000000..711979c81f --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts @@ -0,0 +1,452 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { PaymentRequirements } from "../../../types"; +import { DeferredPaymentPayload, DEFERRRED_SCHEME } from "../../../types/verify/schemes/deferred"; +import { verifyPaymentRequirements, verifyVoucherSignature, verifyOnchainState } from "./verify"; +import { ConnectedClient } from "../../../types/shared/evm/wallet"; +import { verifyVoucher } from "./sign"; +import { getNetworkId } from "../../../shared"; +import { Account, Chain, Transport } from "viem"; + +vi.mock("./sign", () => ({ + verifyVoucher: vi.fn(), +})); + +vi.mock("../../../shared", () => ({ + getNetworkId: vi.fn(), +})); + +const buyerAddress = "0xf33332f96E5EA32c90a5301b646Bf5e93EA1D892"; +const sellerAddress = "0x1234567890123456789012345678901234567890"; +const escrowAddress = "0xffffff12345678901234567890123456789fffff"; +const assetAddress = "0x1111111111111111111111111111111111111111"; +const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; +const voucherSignature = + "0xabf0d28a3df19861fb7b4624d775a8e9064f3d8b285a8c26c5dfd03f445bd1c8331b706a3ac742068bbb1e08795cf0ea7c7e8cb81a715362005f7cde52e2b7e31c"; + +describe("verifyPaymentRequirements", () => { + const mockVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + }; + + const mockPaymentPayload: DeferredPaymentPayload = { + x402Version: 1, + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + payload: { + signature: voucherSignature, + voucher: mockVoucher, + }, + }; + + const mockPaymentRequirements: PaymentRequirements = { + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test resource", + mimeType: "application/json", + payTo: sellerAddress, + maxTimeoutSeconds: 300, + asset: assetAddress, + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + }, + }; + + beforeEach(() => { + vi.clearAllMocks(); + vi.mocked(getNetworkId).mockReturnValue(84532); + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it("should return undefined for valid payment requirements with new voucher", async () => { + const result = await verifyPaymentRequirements(mockPaymentPayload, mockPaymentRequirements); + expect(result).toBeUndefined(); + }); + + it("should return undefined for valid payment requirements with aggregation voucher", async () => { + const aggregationRequirements: PaymentRequirements = { + ...mockPaymentRequirements, + maxAmountRequired: "500000", + extra: { + type: "aggregation", + signature: voucherSignature, + voucher: { + ...mockVoucher, + valueAggregate: "500000", + }, + }, + }; + const result = await verifyPaymentRequirements(mockPaymentPayload, aggregationRequirements); + expect(result).toBeUndefined(); + }); + + it("should return error if payload scheme is not deferred", async () => { + const invalidPayload = { + ...mockPaymentPayload, + scheme: "immediate", + } as unknown as DeferredPaymentPayload; + const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_scheme", + }); + }); + + it("should return error if requirements scheme is not deferred", async () => { + const invalidRequirements = { + ...mockPaymentRequirements, + scheme: "immediate", + } as unknown as PaymentRequirements; + const result = await verifyPaymentRequirements(mockPaymentPayload, invalidRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_requirements_scheme", + }); + }); + + it("should return error if payment payload network does not match payment requirements network", async () => { + const invalidPayload = { + ...mockPaymentPayload, + network: "base", + } as DeferredPaymentPayload; + const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_network_mismatch", + payer: buyerAddress, + }); + }); + + it("should return error if voucher value is insufficient for new voucher", async () => { + const invalidPayload = { + ...mockPaymentPayload, + payload: { + ...mockPaymentPayload.payload, + voucher: { + ...mockVoucher, + valueAggregate: "999999", + }, + }, + }; + const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_value", + payer: buyerAddress, + }); + }); + + it("should return error if voucher value is insufficient for aggregation voucher", async () => { + const aggregationRequirements: PaymentRequirements = { + ...mockPaymentRequirements, + extra: { + type: "aggregation", + signature: voucherSignature, + voucher: { + ...mockVoucher, + valueAggregate: "500000", + }, + }, + }; + const result = await verifyPaymentRequirements(mockPaymentPayload, aggregationRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_value", + payer: buyerAddress, + }); + }); + + it("should return error if payTo does not match voucher seller", async () => { + const invalidRequirements = { + ...mockPaymentRequirements, + payTo: "0x9999999999999999999999999999999999999999", + }; + const result = await verifyPaymentRequirements(mockPaymentPayload, invalidRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_recipient_mismatch", + payer: buyerAddress, + }); + }); + + it("should return error if asset mismatch", async () => { + const invalidPayload = { + ...mockPaymentPayload, + payload: { + ...mockPaymentPayload.payload, + voucher: { + ...mockVoucher, + asset: "0x2222222222222222222222222222222222222222", + }, + }, + }; + const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_asset_mismatch", + payer: buyerAddress, + }); + }); + + it("should return error if network is not supported", async () => { + vi.mocked(getNetworkId).mockImplementation(() => { + throw new Error("Unsupported network"); + }); + const result = await verifyPaymentRequirements(mockPaymentPayload, mockPaymentRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_network_unsupported", + payer: buyerAddress, + }); + }); + + it("should return error if chainId mismatch", async () => { + const invalidPayload = { + ...mockPaymentPayload, + payload: { + ...mockPaymentPayload.payload, + voucher: { + ...mockVoucher, + chainId: 1, + }, + }, + }; + const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_chain_id", + payer: buyerAddress, + }); + }); +}); + +describe("verifyVoucherSignature", () => { + const mockPaymentPayload: DeferredPaymentPayload = { + x402Version: 1, + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + payload: { + signature: voucherSignature, + voucher: { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + }, + }, + }; + + beforeEach(() => { + vi.clearAllMocks(); + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it("should return undefined for valid voucher signature", async () => { + vi.mocked(verifyVoucher).mockResolvedValue(true); + const result = await verifyVoucherSignature(mockPaymentPayload); + expect(result).toBeUndefined(); + expect(vi.mocked(verifyVoucher)).toHaveBeenCalledWith( + mockPaymentPayload.payload.voucher, + voucherSignature, + buyerAddress, + ); + }); + + it("should return error for invalid voucher signature", async () => { + vi.mocked(verifyVoucher).mockResolvedValue(false); + const result = await verifyVoucherSignature(mockPaymentPayload); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_signature", + payer: buyerAddress, + }); + }); +}); + +describe("verifyOnchainState", () => { + const mockPaymentPayload: DeferredPaymentPayload = { + x402Version: 1, + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + payload: { + signature: voucherSignature, + voucher: { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + }, + }, + }; + + const mockPaymentRequirements: PaymentRequirements = { + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test resource", + mimeType: "application/json", + payTo: sellerAddress, + maxTimeoutSeconds: 300, + asset: assetAddress, + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + }, + }; + + let mockClient: ConnectedClient; + + beforeEach(() => { + vi.clearAllMocks(); + vi.mocked(getNetworkId).mockReturnValue(84532); + mockClient = { + chain: { id: 84532 }, + readContract: vi.fn(), + } as unknown as ConnectedClient; + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it("should return undefined for valid onchain state", async () => { + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce({ balance: BigInt("2000000") }) + .mockResolvedValueOnce(false); + + const result = await verifyOnchainState( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + ); + expect(result).toBeUndefined(); + }); + + it("should return error if network is not supported", async () => { + vi.mocked(getNetworkId).mockImplementation(() => { + throw new Error("Unsupported network"); + }); + const result = await verifyOnchainState( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_network_unsupported", + payer: buyerAddress, + }); + }); + + it("should return error if client network mismatch", async () => { + mockClient.chain.id = 1; + const result = await verifyOnchainState( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_client_network", + payer: buyerAddress, + }); + }); + + it("should return error if balance check fails", async () => { + vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); + const result = await verifyOnchainState( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "insufficient_funds_contract_call_failed", + payer: buyerAddress, + }); + }); + + it("should return error if insufficient balance", async () => { + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce({ balance: BigInt("500000") }) + .mockResolvedValueOnce(false); + + const result = await verifyOnchainState( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "insufficient_funds", + payer: buyerAddress, + }); + }); + + it("should return error if voucher id check fails", async () => { + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce({ balance: BigInt("2000000") }) + .mockRejectedValueOnce(new Error("Contract call failed")); + + const result = await verifyOnchainState( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_contract_call_failed", + payer: buyerAddress, + }); + }); + + it("should return error if voucher already claimed", async () => { + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce({ balance: BigInt("2000000") }) + .mockResolvedValueOnce(true); + + const result = await verifyOnchainState( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_already_claimed", + payer: buyerAddress, + }); + }); +}); From c1c34d4ef7021bb75e548f7b2f89a44b7d995410 Mon Sep 17 00:00:00 2001 From: Chris Whited Date: Mon, 21 Jul 2025 21:56:12 +0100 Subject: [PATCH 021/116] feat(x402-fetch): implement deferred scheme fetch wrapper (#4) * feat(x402-fetch): implement deferred scheme fetch wrapper * feat(x402-fetch): remove maxAggregateValue check * feat(x402-fetch): PR feedback. rename transaction to request. use constants --- .../packages/x402-fetch/src/index.test.ts | 173 +++++++++++++++++- typescript/packages/x402-fetch/src/index.ts | 128 ++++++++++++- .../src/client/selectPaymentRequirements.ts | 12 +- .../x402/src/schemes/deferred/evm/client.ts | 13 +- typescript/packages/x402/src/schemes/index.ts | 1 + .../x402/src/types/verify/schemes/index.ts | 8 +- typescript/pnpm-workspace.yaml | 7 + 7 files changed, 318 insertions(+), 24 deletions(-) diff --git a/typescript/packages/x402-fetch/src/index.test.ts b/typescript/packages/x402-fetch/src/index.test.ts index 333b89680d..1eb0f600c8 100644 --- a/typescript/packages/x402-fetch/src/index.test.ts +++ b/typescript/packages/x402-fetch/src/index.test.ts @@ -1,6 +1,6 @@ -import { describe, it, expect, vi, beforeEach } from "vitest"; -import { wrapFetchWithPayment } from "./index"; -import { evm, PaymentRequirements } from "x402/types"; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { DeferredPaymentRequirements, evm, PaymentRequirements } from "x402/types"; +import { wrapFetchWithPayment, wrapFetchWithDeferredPayment } from "./index"; vi.mock("x402/client", () => ({ createPaymentHeader: vi.fn(), @@ -167,3 +167,170 @@ describe("fetchWithPayment()", () => { ).rejects.toBe(paymentError); }); }); + +describe("fetchWithDeferredPayment()", () => { + let mockFetch: ReturnType; + let mockWalletClient: typeof evm.SignerWallet; + let wrappedDeferredFetch: ReturnType; + const escrowAddress = "0xffffff12345678901234567890123456789fffff"; + const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; + const validPaymentRequirements: Array = [ + { + scheme: "deferred", + network: "base-sepolia", + maxAmountRequired: "100000", // 0.1 USDC in base units + resource: "https://api.example.com/resource", + description: "Test payment", + mimeType: "application/json", + payTo: "0x1234567890123456789012345678901234567890", + maxTimeoutSeconds: 300, + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", // USDC on base-sepolia + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + }, + }, + ]; + + const createResponse = (status: number, data?: unknown): Response => { + return new Response(JSON.stringify(data), { + status, + statusText: status === 402 ? "Payment Required" : "Not Found", + headers: new Headers(), + }); + }; + + beforeEach(async () => { + vi.resetAllMocks(); + + mockFetch = vi.fn(); + + mockWalletClient = { + signMessage: vi.fn(), + } as unknown as typeof evm.SignerWallet; + + // Mock payment requirements selector + const { selectPaymentRequirements } = await import("x402/client"); + (selectPaymentRequirements as ReturnType).mockImplementation( + (requirements, _) => requirements[0], + ); + + wrappedDeferredFetch = wrapFetchWithDeferredPayment(mockFetch, mockWalletClient); + }); + + it("should return the original response for non-402 status codes", async () => { + const successResponse = createResponse(200, { data: "success" }); + mockFetch.mockResolvedValue(successResponse); + + const result = await wrappedDeferredFetch("https://api.example.com"); + + expect(result).toBe(successResponse); + expect(mockFetch).toHaveBeenCalledWith("https://api.example.com", undefined); + }); + + it("should handle 402 errors and retry with payment header", async () => { + const paymentHeader = "payment-header-value"; + const successResponse = createResponse(200, { data: "success" }); + + const { createPaymentHeader, selectPaymentRequirements } = await import("x402/client"); + (createPaymentHeader as ReturnType).mockResolvedValue(paymentHeader); + (selectPaymentRequirements as ReturnType).mockImplementation( + (requirements, _) => requirements[0], + ); + mockFetch + .mockResolvedValueOnce( + createResponse(402, { accepts: validPaymentRequirements, x402Version: 1 }), + ) + .mockResolvedValueOnce(successResponse); + + const result = await wrappedDeferredFetch("https://api.example.com", { + method: "GET", + headers: { "Content-Type": "application/json" }, + } as RequestInitWithRetry); + + expect(result).toBe(successResponse); + expect(selectPaymentRequirements).toHaveBeenCalledWith( + validPaymentRequirements, + undefined, + "deferred", + ); + expect(createPaymentHeader).toHaveBeenCalledWith( + mockWalletClient, + 1, + validPaymentRequirements[0], + ); + expect(mockFetch).toHaveBeenCalledTimes(2); + expect(mockFetch).toHaveBeenLastCalledWith("https://api.example.com", { + method: "GET", + headers: { + "Content-Type": "application/json", + "X-PAYMENT": paymentHeader, + "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", + }, + __is402Retry: true, + } as RequestInitWithRetry); + }); + + it("should not retry if already retried", async () => { + const errorResponse = createResponse(402, { + accepts: validPaymentRequirements, + x402Version: 1, + }); + mockFetch.mockResolvedValue(errorResponse); + + await expect( + wrappedDeferredFetch("https://api.example.com", { + __is402Retry: true, + } as RequestInitWithRetry), + ).rejects.toThrow("Payment already attempted"); + }); + + it("should reject if missing request config", async () => { + const errorResponse = createResponse(402, { + accepts: validPaymentRequirements, + x402Version: 1, + }); + mockFetch.mockResolvedValue(errorResponse); + + await expect(wrappedDeferredFetch("https://api.example.com")).rejects.toThrow( + "Missing fetch request configuration", + ); + }); + + it("should reject if payment amount exceeds maximum transaction amount", async () => { + const errorResponse = createResponse(402, { + accepts: [ + { + ...validPaymentRequirements[0], + maxAmountRequired: "200000", // 0.2 USDC, which exceeds our default max of 0.1 USDC + }, + ], + x402Version: 1, + }); + mockFetch.mockResolvedValue(errorResponse); + + await expect( + wrappedDeferredFetch("https://api.example.com", { + method: "GET", + } as RequestInitWithRetry), + ).rejects.toThrow("Payment amount exceeds maximum request allowed amount"); + }); + + it("should reject if payment header creation fails", async () => { + const paymentError = new Error("Payment failed"); + const { createPaymentHeader } = await import("x402/client"); + (createPaymentHeader as ReturnType).mockRejectedValue(paymentError); + mockFetch.mockResolvedValue( + createResponse(402, { accepts: validPaymentRequirements, x402Version: 1 }), + ); + + await expect( + wrappedDeferredFetch("https://api.example.com", { + method: "GET", + } as RequestInitWithRetry), + ).rejects.toBe(paymentError); + }); +}); diff --git a/typescript/packages/x402-fetch/src/index.ts b/typescript/packages/x402-fetch/src/index.ts index 16c3b056ef..b615e34d36 100644 --- a/typescript/packages/x402-fetch/src/index.ts +++ b/typescript/packages/x402-fetch/src/index.ts @@ -1,18 +1,22 @@ +import { + createPaymentHeader, + PaymentRequirementsSelector, + selectPaymentRequirements, +} from "x402/client"; import { ChainIdToNetwork, - PaymentRequirementsSchema, - Signer, + DeferredPaymentRequirementsSchema, + DEFERRRED_SCHEME, evm, + EXACT_SCHEME, + PaymentRequirementsSchema, + Wallet, + Network, MultiNetworkSigner, isMultiNetworkSigner, isSvmSignerWallet, - Network, + Signer, } from "x402/types"; -import { - createPaymentHeader, - PaymentRequirementsSelector, - selectPaymentRequirements, -} from "x402/client"; /** * Enables the payment of APIs using the x402 payment protocol. @@ -75,7 +79,7 @@ export function wrapFetchWithPayment( const selectedPaymentRequirements = paymentRequirementsSelector( parsedPaymentRequirements, network, - "exact", + EXACT_SCHEME, ); if (BigInt(selectedPaymentRequirements.maxAmountRequired) > maxValue) { @@ -111,6 +115,112 @@ export function wrapFetchWithPayment( }; } +/** + * Enables the payment of APIs using the x402 deferred payment protocol. + * + * This function wraps the native fetch API to automatically handle 402 Payment Required responses + * by creating and sending a payment header. It will: + * 1. Make the initial request + * 2. If a 402 response is received, parse the payment requirements + * 3. Verify the payment amount is within the allowed maximum (maxTransactionValue param) + * 5. Create a payment header using the provided wallet client + * 6. Retry the request with the payment header + * + * When to use: + * In the instance that the paid api endpoint being requested supports the x402 deferred scheme. + * + * @param fetch - The fetch function to wrap (typically globalThis.fetch) + * @param walletClient - The wallet client used to sign payment messages + * @param maxRequestValue - The maximum allowed payment amount in base units (defaults to 0.1 USDC) for any given request + * @param paymentRequirementsSelector - A function that selects the payment requirements from the response + * @returns A wrapped fetch function that handles 402 responses automatically + * + * @example Default amounts + * ```typescript + * const wallet = new SignerWallet(...); + * const fetchWithDeferredPay = wrapFetchWithDeferredPayment(fetch, wallet); + * + * // Make a request that may require payment + * const response = await fetchWithDeferredPay('https://api.example.com/paid-endpoint'); + * ``` + * + * @example Set max aggregate and transactional amounts + * ```typescript + * const wallet = new SignerWallet(...); + * const fetchWithDeferredPay = wrapFetchWithDeferredPayment(fetch, wallet, BigInt(0.2 * 10 ** 6)); + * + * // Make a request that may require payment + * const response = await fetchWithDeferredPay('https://api.example.com/paid-endpoint'); + * ``` + * + * @throws {Error} If the transaction payment amount exceeds the transaction maximum allowed value + * @throws {Error} If the request configuration is missing + * @throws {Error} If a payment has already been attempted for this request + * @throws {Error} If there's an error creating the payment header + */ +export function wrapFetchWithDeferredPayment( + fetch: typeof globalThis.fetch, + walletClient: Wallet, + maxRequestValue: bigint = BigInt(0.1 * 10 ** 6), // Default to 0.10 USDC + paymentRequirementsSelector: PaymentRequirementsSelector = selectPaymentRequirements, +) { + return async (input: RequestInfo, init?: RequestInit) => { + const response = await fetch(input, init); + + if (response.status !== 402) { + return response; + } + + const { x402Version, accepts } = (await response.json()) as { + x402Version: number; + accepts: unknown[]; + }; + const parsedPaymentRequirements = accepts.map(x => PaymentRequirementsSchema.parse(x)); + + const chainId = evm.isSignerWallet(walletClient) ? walletClient.chain?.id : undefined; + const selectedPaymentRequirements = paymentRequirementsSelector( + parsedPaymentRequirements, + chainId ? ChainIdToNetwork[chainId] : undefined, + DEFERRRED_SCHEME, + ); + const selectedDeferredPaymentRequirements = DeferredPaymentRequirementsSchema.parse( + selectedPaymentRequirements, + ); + + const transactionAmount = BigInt(selectedDeferredPaymentRequirements.maxAmountRequired); + if (transactionAmount > maxRequestValue) { + throw new Error("Payment amount exceeds maximum request allowed amount"); + } + + const paymentHeader = await createPaymentHeader( + walletClient, + x402Version, + selectedDeferredPaymentRequirements, + ); + + if (!init) { + throw new Error("Missing fetch request configuration"); + } + + if ((init as { __is402Retry?: boolean }).__is402Retry) { + throw new Error("Payment already attempted"); + } + + const newInit = { + ...init, + headers: { + ...(init.headers || {}), + "X-PAYMENT": paymentHeader, + "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", + }, + __is402Retry: true, + }; + + const paymentHeaderSignedResponse = await fetch(input, newInit); + return paymentHeaderSignedResponse; + }; +} + export { decodeXPaymentResponse } from "x402/shared"; export { createSigner, type Signer, type MultiNetworkSigner } from "x402/types"; export type { Hex } from "viem"; diff --git a/typescript/packages/x402/src/client/selectPaymentRequirements.ts b/typescript/packages/x402/src/client/selectPaymentRequirements.ts index 1e06516afb..09dd713454 100644 --- a/typescript/packages/x402/src/client/selectPaymentRequirements.ts +++ b/typescript/packages/x402/src/client/selectPaymentRequirements.ts @@ -1,7 +1,6 @@ -import { Network, PaymentRequirements } from "../types"; import { getUsdcChainConfigForChain } from "../shared/evm"; import { getNetworkId } from "../shared/network"; -import { EXACT_SCHEME } from "../types/verify/schemes/exact"; +import { EXACT_SCHEME, Network, PaymentRequirements } from "../types"; /** * Default selector for payment requirements. @@ -14,7 +13,7 @@ import { EXACT_SCHEME } from "../types/verify/schemes/exact"; * @returns The payment requirement that is the most appropriate for the user. */ export function selectPaymentRequirements( - paymentRequirements: PaymentRequirements[], + paymentRequirements: Array, network?: Network | Network[], scheme?: typeof EXACT_SCHEME, ): PaymentRequirements { @@ -42,7 +41,10 @@ export function selectPaymentRequirements( // Filter down to USDC requirements const usdcRequirements = broadlyAcceptedPaymentRequirements.filter(requirement => { // If the address is a USDC address, we return it. - return requirement.asset === getUsdcChainConfigForChain(getNetworkId(requirement.network))?.usdcAddress; + return ( + requirement.asset === + getUsdcChainConfigForChain(getNetworkId(requirement.network))?.usdcAddress + ); }); // Prioritize USDC requirements if available @@ -65,4 +67,4 @@ export function selectPaymentRequirements( * @param scheme - The scheme to check against. If not provided, the scheme will not be checked. * @returns The payment requirement that is the most appropriate for the user. */ -export type PaymentRequirementsSelector = (paymentRequirements: PaymentRequirements[], network?: Network | Network[], scheme?: typeof EXACT_SCHEME) => PaymentRequirements; +export type PaymentRequirementsSelector = (paymentRequirements: Array, network?: Network | Network[], scheme?: typeof EXACT_SCHEME) => PaymentRequirements; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index 2292ad360d..d75bbb0fb5 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -1,17 +1,18 @@ import { Address, Chain, Hex, LocalAccount, Transport } from "viem"; +import { getNetworkId } from "../../../shared/network"; import { isSignerWallet, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, PaymentRequirements, UnsignedPaymentPayload } from "../../../types/verify"; -import { signVoucher, verifyVoucher } from "./sign"; -import { encodePayment } from "./utils/paymentUtils"; import { DeferredEvmPayloadVoucher, DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, DeferredEvmPaymentRequirementsExtraNewVoucherSchema, DeferredPaymentRequirementsSchema, + DEFERRRED_SCHEME, + UnsignedDeferredPaymentPayload, UnsignedDeferredPaymentPayloadSchema, } from "../../../types/verify/schemes/deferred"; -import { getNetworkId } from "../../../shared/network"; -import { DEFERRRED_SCHEME } from "../../../types/verify/schemes/deferred"; +import { signVoucher, verifyVoucher } from "./sign"; +import { encodePayment } from "./utils/paymentUtils"; /** * Prepares an unsigned payment header with the given sender address and payment requirements. @@ -25,7 +26,7 @@ export async function preparePaymentHeader( buyer: Address, x402Version: number, paymentRequirements: PaymentRequirements, -): Promise { +): Promise { const deferredPaymentRequirements = DeferredPaymentRequirementsSchema.parse(paymentRequirements); const voucher = @@ -41,7 +42,7 @@ export async function preparePaymentHeader( signature: undefined, voucher: voucher, }, - }; + } as const satisfies UnsignedDeferredPaymentPayload; } /** diff --git a/typescript/packages/x402/src/schemes/index.ts b/typescript/packages/x402/src/schemes/index.ts index 40d12013d5..477e67bb3e 100644 --- a/typescript/packages/x402/src/schemes/index.ts +++ b/typescript/packages/x402/src/schemes/index.ts @@ -1,2 +1,3 @@ +export * as deferred from "./deferred"; export * as exact from "./exact"; export * from "./utils"; diff --git a/typescript/packages/x402/src/types/verify/schemes/index.ts b/typescript/packages/x402/src/types/verify/schemes/index.ts index 70740d00e5..52f109b7e5 100644 --- a/typescript/packages/x402/src/types/verify/schemes/index.ts +++ b/typescript/packages/x402/src/types/verify/schemes/index.ts @@ -1,3 +1,9 @@ +import { DEFERRRED_SCHEME } from "./deferred"; +import { EXACT_SCHEME } from "./exact"; + export * from "./base"; -export * from "./exact"; export * from "./deferred"; +export * from "./exact"; + +export const SCHEMES = [EXACT_SCHEME, DEFERRRED_SCHEME] as const; +export type SCHEMES = (typeof SCHEMES)[number]; diff --git a/typescript/pnpm-workspace.yaml b/typescript/pnpm-workspace.yaml index 6aff8b61f3..e3e083b0f4 100644 --- a/typescript/pnpm-workspace.yaml +++ b/typescript/pnpm-workspace.yaml @@ -5,3 +5,10 @@ packages: - site ignoredBuiltDependencies: - esbuild +onlyBuiltDependencies: + - bigint-buffer + - bufferutil + - keccak + - sharp + - unrs-resolver + - utf-8-validate From adbc243d1afa9df5ac1f656485007d97c1e3d1ff Mon Sep 17 00:00:00 2001 From: Chris Whited Date: Mon, 21 Jul 2025 22:11:32 +0100 Subject: [PATCH 022/116] feat(x402-fetch): update README to include api for wrapFetchWithDeferredPayment (#5) * feat(x402-fetch): update README to include api for wrapFetchWithDeferredPaymetn * feat(x402-fetch): typo --- typescript/packages/x402-fetch/README.md | 89 ++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/typescript/packages/x402-fetch/README.md b/typescript/packages/x402-fetch/README.md index 5b3bfd3886..c84f9dc847 100644 --- a/typescript/packages/x402-fetch/README.md +++ b/typescript/packages/x402-fetch/README.md @@ -10,6 +10,8 @@ npm install x402-fetch ## Quick Start +### Exact Scheme + ```typescript import { createWalletClient, http } from "viem"; import { privateKeyToAccount } from "viem/accounts"; @@ -35,6 +37,33 @@ const response = await fetchWithPay("https://api.example.com/paid-endpoint", { const data = await response.json(); ``` +### Deferred Scheme + +```typescript +import { createWalletClient, http } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { wrapFetchWithPayment } from "x402-fetch"; +import { baseSepolia } from "viem/chains"; + +// Create a wallet client +const account = privateKeyToAccount("0xYourPrivateKey"); +const client = createWalletClient({ + account, + transport: http(), + chain: baseSepolia, +}); + +// Wrap the fetch function with deferred payment handling +const fetchWithDeferredPay = wrapFetchWithDeferredPayment(fetch, client); + +// Make a request that may require payment +const response = await fetchWithDeferredPay("https://api.example.com/paid-endpoint", { + method: "GET", +}); + +const data = await response.json(); +``` + ## API ### `wrapFetchWithPayment(fetch, walletClient, maxValue?, paymentRequirementsSelector?)` @@ -51,6 +80,7 @@ Wraps the native fetch API to handle 402 Payment Required responses automaticall #### Returns A wrapped fetch function that automatically handles 402 responses by: + 1. Making the initial request 2. If a 402 response is received, parsing the payment requirements 3. Verifying the payment amount is within the allowed maximum @@ -92,3 +122,62 @@ fetchWithPay(API_URL, { }); ``` +### `wrapFetchWithDeferredPayment(fetch, walletClient, maxRequestValue?, paymentRequirementsSelector?)` + +Wraps the native fetch API to handle 402 Deferred Payment Required responses automatically. + +#### When to use + +The `wrapFetchWithDeferredPayment` method should be used if the facilitator/seller being called is configured to allow for deferred/aggregated payments using a configured escrow account. The biggest difference is that the `wrapFetchWithPayment` method, if a 402 response is returned, will process the payment for each request. The `wrapFetchWithDeferredPayment` and `deferred` payment schemes allow the buyer (the user of this library) to make _multiple_ requests where the amount is aggregated and then paid off with **one** onchain transaciton covering all requests on a given voucher. + +#### Parameters + +- `fetch`: The fetch function to wrap (typically `globalThis.fetch`) +- `walletClient`: The wallet client used to sign payment messages (must implement the x402 wallet interface) +- `maxRequestValue`: Optional maximum allowed payment amount, for any given request, in base units (defaults to 0.1 USDC) +- `paymentRequirementsSelector`: Optional function to select payment requirements from the response (defaults to `selectPaymentRequirements`) + +#### Returns + +A wrapped fetch function that automatically handles 402 deferred payment responses by: + +1. Making the initial request +2. If a 402 response is received, parsing the payment requirements +3. Verifying the payment amount is within the allowed maximum +4. Creating a payment header using the provided wallet client +5. Retrying the request with the payment header + +## Example + +```typescript +import { config } from "dotenv"; +import { createWalletClient, http } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { wrapFetchWithPayment } from "x402-fetch"; +import { baseSepolia } from "viem/chains"; + +config(); + +const { PRIVATE_KEY, API_URL } = process.env; + +const account = privateKeyToAccount(PRIVATE_KEY as `0x${string}`); +const client = createWalletClient({ + account, + transport: http(), + chain: baseSepolia, +}); + +const fetchWithDeferredPay = wrapFetchWithDeferredPayment(fetch, client); + +// Make a request to a paid API endpoint +fetchWithDeferredPay(API_URL, { + method: "GET", +}) + .then(async response => { + const data = await response.json(); + console.log(data); + }) + .catch(error => { + console.error(error); + }); +``` From 52e96cc738a99059a64422e96946feb1b25cb862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 18 Jul 2025 15:12:38 -0300 Subject: [PATCH 023/116] fix: change id re-usability behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/verify.test.ts | 42 +---------- .../x402/src/schemes/deferred/evm/verify.ts | 49 +++++-------- .../src/types/shared/evm/deferredEscrowABI.ts | 71 +++++++++++++++++++ .../x402/src/types/verify/schemes/deferred.ts | 2 - 4 files changed, 89 insertions(+), 75 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts index 711979c81f..ce97828155 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts @@ -343,9 +343,7 @@ describe("verifyOnchainState", () => { }); it("should return undefined for valid onchain state", async () => { - vi.mocked(mockClient.readContract) - .mockResolvedValueOnce({ balance: BigInt("2000000") }) - .mockResolvedValueOnce(false); + vi.mocked(mockClient.readContract).mockResolvedValueOnce(true); const result = await verifyOnchainState( mockClient, @@ -400,9 +398,7 @@ describe("verifyOnchainState", () => { }); it("should return error if insufficient balance", async () => { - vi.mocked(mockClient.readContract) - .mockResolvedValueOnce({ balance: BigInt("500000") }) - .mockResolvedValueOnce(false); + vi.mocked(mockClient.readContract).mockResolvedValueOnce(false); const result = await verifyOnchainState( mockClient, @@ -415,38 +411,4 @@ describe("verifyOnchainState", () => { payer: buyerAddress, }); }); - - it("should return error if voucher id check fails", async () => { - vi.mocked(mockClient.readContract) - .mockResolvedValueOnce({ balance: BigInt("2000000") }) - .mockRejectedValueOnce(new Error("Contract call failed")); - - const result = await verifyOnchainState( - mockClient, - mockPaymentPayload, - mockPaymentRequirements, - ); - expect(result).toEqual({ - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_contract_call_failed", - payer: buyerAddress, - }); - }); - - it("should return error if voucher already claimed", async () => { - vi.mocked(mockClient.readContract) - .mockResolvedValueOnce({ balance: BigInt("2000000") }) - .mockResolvedValueOnce(true); - - const result = await verifyOnchainState( - mockClient, - mockPaymentPayload, - mockPaymentRequirements, - ); - expect(result).toEqual({ - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_already_claimed", - payer: buyerAddress, - }); - }); }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index d195f0ff11..0e30e0a152 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -145,7 +145,6 @@ export async function verifyVoucherSignature(paymentPayload: DeferredPaymentPayl * * - ✅ (on-chain) Verifies the client is connected to the chain specified in the payment requirements * - ✅ (on-chain) Verifies buyer has sufficient asset balance - * - ✅ (on-chain) Verifies the voucher id has not been already claimed * - ⌛ TODO: Simulate the transaction to ensure it will succeed * * @param client - The client to use for the onchain state verification @@ -183,19 +182,27 @@ export async function verifyOnchainState< } // Verify buyer has sufficient asset balance in the escrow contract - let balance: bigint; + // We delegate the actual calculation to the escrow contract + let isVoucherCollectable: boolean; try { - const account = await client.readContract({ + isVoucherCollectable = await client.readContract({ address: paymentPayload.payload.voucher.escrow as Address, abi: deferredEscrowABI, - functionName: "accounts", + functionName: "isVoucherCollectable", args: [ - paymentPayload.payload.voucher.buyer as Address, - paymentPayload.payload.voucher.seller as Address, - paymentPayload.payload.voucher.asset as Address, + { + id: paymentPayload.payload.voucher.id as Hex, + buyer: paymentPayload.payload.voucher.buyer as Address, + seller: paymentPayload.payload.voucher.seller as Address, + valueAggregate: BigInt(paymentPayload.payload.voucher.valueAggregate), + asset: paymentPayload.payload.voucher.asset as Address, + timestamp: BigInt(paymentPayload.payload.voucher.timestamp), + nonce: BigInt(paymentPayload.payload.voucher.nonce), + escrow: paymentPayload.payload.voucher.escrow as Address, + chainId: BigInt(paymentPayload.payload.voucher.chainId), + }, ], }); - balance = account.balance; } catch { return { isValid: false, @@ -203,35 +210,11 @@ export async function verifyOnchainState< payer: paymentPayload.payload.voucher.buyer, }; } - if (balance < BigInt(paymentPayload.payload.voucher.valueAggregate)) { + if (!isVoucherCollectable) { return { isValid: false, invalidReason: "insufficient_funds", payer: paymentPayload.payload.voucher.buyer, }; } - - // Verify voucher id has not been already claimed - let isCollected: boolean; - try { - isCollected = await client.readContract({ - address: paymentPayload.payload.voucher.escrow as Address, - abi: deferredEscrowABI, - functionName: "isCollected", - args: [paymentPayload.payload.voucher.id as Hex], - }); - } catch { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_contract_call_failed", - payer: paymentPayload.payload.voucher.buyer, - }; - } - if (isCollected) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_already_claimed", - payer: paymentPayload.payload.voucher.buyer, - }; - } } diff --git a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts index 2c3a628ebd..24f40626dd 100644 --- a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts +++ b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts @@ -76,4 +76,75 @@ export const deferredEscrowABI = [ stateMutability: "view", type: "function", }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "id", + type: "bytes32", + }, + { + internalType: "address", + name: "buyer", + type: "address", + }, + { + internalType: "address", + name: "seller", + type: "address", + }, + { + internalType: "uint256", + name: "valueAggregate", + type: "uint256", + }, + { + internalType: "address", + name: "asset", + type: "address", + }, + { + internalType: "uint64", + name: "timestamp", + type: "uint64", + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + internalType: "address", + name: "escrow", + type: "address", + }, + { + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + // { + // internalType: "uint64", + // name: "expiry", + // type: "uint64", + // }, + ], + internalType: "struct IDeferredPaymentEscrow.Voucher", + name: "voucher", + type: "tuple", + }, + ], + name: "isVoucherCollectable", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, ] as const; diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index cbd8752d04..a3c6f0c573 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -18,8 +18,6 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_voucher_value", "invalid_deferred_evm_payload_recipient_mismatch", "invalid_deferred_evm_payload_asset_mismatch", - "invalid_deferred_evm_payload_voucher_already_claimed", - "invalid_deferred_evm_payload_voucher_contract_call_failed", "invalid_deferred_evm_payload_signature", "invalid_deferred_evm_payload_no_longer_valid", ] as const; From d5e519cb23b19db35e6ab87071d87a21a411afbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 18 Jul 2025 16:10:12 -0300 Subject: [PATCH 024/116] feat: add expiry to voucher, add some more tests as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/client.test.ts | 163 +++++++++++++++++- .../x402/src/schemes/deferred/evm/client.ts | 28 ++- .../src/schemes/deferred/evm/sign.test.ts | 48 +++++- .../x402/src/schemes/deferred/evm/sign.ts | 4 +- .../src/schemes/deferred/evm/verify.test.ts | 45 ++++- .../x402/src/schemes/deferred/evm/verify.ts | 19 ++ .../src/types/shared/evm/deferredEscrowABI.ts | 10 +- .../x402/src/types/shared/evm/typedData.ts | 3 +- .../x402/src/types/verify/schemes/deferred.ts | 3 + 9 files changed, 300 insertions(+), 23 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts index 0a9849f32b..e3b7df7cd5 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -1,7 +1,12 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createSigner } from "../../../types/shared/evm"; import { PaymentRequirements } from "../../../types/verify"; -import { createPaymentHeader, preparePaymentHeader, signPaymentHeader } from "./client"; +import { + createPaymentHeader, + preparePaymentHeader, + signPaymentHeader, + createNewVoucher, +} from "./client"; import { DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, DeferredPaymentPayloadSchema, @@ -47,7 +52,7 @@ describe("preparePaymentHeader: new voucher", () => { beforeEach(() => { vi.useFakeTimers(); // Set a fixed time for consistent testing - vi.setSystemTime(new Date("2024-01-01T00:00:00Z")); + vi.setSystemTime(new Date("2024-05-20T00:00:00Z")); vi.clearAllMocks(); }); @@ -77,6 +82,7 @@ describe("preparePaymentHeader: new voucher", () => { nonce: 0, escrow: escrowAddress, chainId: 84532, + expiry: expect.any(Number), }, }, }); @@ -108,6 +114,87 @@ describe("preparePaymentHeader: new voucher", () => { }); }); +describe("createNewVoucher", () => { + const mockPaymentRequirements: PaymentRequirements = { + scheme: "deferred", + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test resource", + mimeType: "application/json", + payTo: sellerAddress, + maxTimeoutSeconds: 300, + asset: assetAddress, + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + }, + }; + + beforeEach(() => { + vi.useFakeTimers(); + // Set a fixed time for consistent testing + vi.setSystemTime(new Date("2024-05-20T00:00:00Z")); + vi.clearAllMocks(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it("should create a valid new voucher with correct properties", () => { + const voucher = createNewVoucher(buyerAddress, mockPaymentRequirements); + + expect(voucher).toEqual({ + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: Math.floor(Date.now() / 1000), + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30, // 30 days + }); + }); + + it("should use buyer address as provided", () => { + const differentBuyerAddress = "0x9876543210987654321098765432109876543210"; + const voucher = createNewVoucher(differentBuyerAddress, mockPaymentRequirements); + + expect(voucher.buyer).toBe(differentBuyerAddress); + }); + + it("should set nonce to 0 for new vouchers", () => { + const voucher = createNewVoucher(buyerAddress, mockPaymentRequirements); + + expect(voucher.nonce).toBe(0); + }); + + it("should calculate expiry time correctly", () => { + const currentTime = Math.floor(Date.now() / 1000); + const voucher = createNewVoucher(buyerAddress, mockPaymentRequirements); + + expect(voucher.expiry).toBe(currentTime + 60 * 60 * 24 * 30); + }); + + it("should throw if payment requirements are invalid", () => { + const invalidRequirements = { + ...mockPaymentRequirements, + extra: { + type: "new", + // Missing voucher property + }, + } as PaymentRequirements; + + expect(() => createNewVoucher(buyerAddress, invalidRequirements)).toThrow(); + }); +}); + describe("preparePaymentHeader: aggregated voucher", () => { const mockAggregatedPaymentRequirements: PaymentRequirements = { scheme: "deferred", @@ -122,7 +209,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { extra: { type: "aggregation", signature: - "0xabf0d28a3df19861fb7b4624d775a8e9064f3d8b285a8c26c5dfd03f445bd1c8331b706a3ac742068bbb1e08795cf0ea7c7e8cb81a715362005f7cde52e2b7e31c", + "0x4f47e2cb1858b4d980c962bdb198c564acedec0e5d5e958431339b59130c416122faa4b8f2f34e1a5a2a3b6401cc938712abc6939ba8ab6106fb1efbb50a87e61b", voucher: { id: voucherId, buyer: buyerAddress, @@ -133,6 +220,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { nonce: 0, escrow: escrowAddress, chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days }, }, }; @@ -140,7 +228,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { beforeEach(() => { vi.useFakeTimers(); // Set a fixed time for consistent testing - vi.setSystemTime(new Date("2024-01-01T00:00:00Z")); + vi.setSystemTime(new Date("2024-05-20T00:00:00Z")); vi.clearAllMocks(); }); @@ -178,6 +266,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { nonce: 1, escrow: escrowAddress, chainId: 84532, + expiry: expect.any(Number), }, }, }); @@ -206,6 +295,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { "nonce", "escrow", "chainId", + "expiry", ]; for (const field of requiredFields) { const badPaymentRequirements = structuredClone(mockAggregatedPaymentRequirements); @@ -226,6 +316,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { "nonce", "escrow", "chainId", + "expiry", ]; for (const field of requiredFields) { const badPaymentRequirements = structuredClone(mockAggregatedPaymentRequirements); @@ -239,6 +330,55 @@ describe("preparePaymentHeader: aggregated voucher", () => { const result = await preparePaymentHeader(buyerAddress, 2, mockAggregatedPaymentRequirements); expect(result.x402Version).toBe(2); }); + + it("should revert if voucher seller doesn't match payment requirements", async () => { + const paymentRequirements = structuredClone(mockAggregatedPaymentRequirements); + paymentRequirements.payTo = "0x9999999999999999999999999999999999999999"; + + await expect(preparePaymentHeader(buyerAddress, 1, paymentRequirements)).rejects.toThrow( + "Invalid voucher seller", + ); + }); + + it("should revert if voucher asset doesn't match payment requirements", async () => { + const paymentRequirements = structuredClone(mockAggregatedPaymentRequirements); + paymentRequirements.asset = "0x2222222222222222222222222222222222222222"; + + await expect(preparePaymentHeader(buyerAddress, 1, paymentRequirements)).rejects.toThrow( + "Invalid voucher asset", + ); + }); + + it("should revert if voucher chainId doesn't match payment requirements", async () => { + const paymentRequirements = structuredClone(mockAggregatedPaymentRequirements); + paymentRequirements.network = "base"; + + await expect(preparePaymentHeader(buyerAddress, 1, paymentRequirements)).rejects.toThrow( + "Invalid voucher chainId", + ); + }); + + it("should revert if voucher is expired", async () => { + const paymentRequirements = structuredClone(mockAggregatedPaymentRequirements); + // Set voucher expiry to a past date + // @ts-expect-error - TODO: fix this + paymentRequirements.extra!.voucher.expiry = 1715769600 - 1; // 1 second before timestamp + + await expect(preparePaymentHeader(buyerAddress, 1, paymentRequirements)).rejects.toThrow( + "Voucher expired", + ); + }); + + it("should revert if voucher timestamp is in the future", async () => { + const paymentRequirements = structuredClone(mockAggregatedPaymentRequirements); + // Set voucher timestamp to future + // @ts-expect-error - TODO: fix this + paymentRequirements.extra!.voucher.timestamp = Math.floor(Date.now() / 1000) + 3600; // 1 hour in future + + await expect(preparePaymentHeader(buyerAddress, 1, paymentRequirements)).rejects.toThrow( + "Voucher timestamp is in the future", + ); + }); }); describe("signPaymentHeader", () => { @@ -258,11 +398,12 @@ describe("signPaymentHeader", () => { nonce: 0, escrow: escrowAddress, chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days }, }, }; const mockVoucherSignature = - "0xabf0d28a3df19861fb7b4624d775a8e9064f3d8b285a8c26c5dfd03f445bd1c8331b706a3ac742068bbb1e08795cf0ea7c7e8cb81a715362005f7cde52e2b7e31c"; + "0x4f47e2cb1858b4d980c962bdb198c564acedec0e5d5e958431339b59130c416122faa4b8f2f34e1a5a2a3b6401cc938712abc6939ba8ab6106fb1efbb50a87e61b"; it("should sign the payment header and return a complete payload", async () => { const signedPaymentPayload = await signPaymentHeader(buyer, mockUnsignedHeader); @@ -307,7 +448,7 @@ describe("createPaymentHeader", () => { extra: { type: "aggregation", signature: - "0xabf0d28a3df19861fb7b4624d775a8e9064f3d8b285a8c26c5dfd03f445bd1c8331b706a3ac742068bbb1e08795cf0ea7c7e8cb81a715362005f7cde52e2b7e31c", + "0x4f47e2cb1858b4d980c962bdb198c564acedec0e5d5e958431339b59130c416122faa4b8f2f34e1a5a2a3b6401cc938712abc6939ba8ab6106fb1efbb50a87e61b", voucher: { id: voucherId, buyer: buyerAddress, @@ -318,6 +459,7 @@ describe("createPaymentHeader", () => { nonce: 0, escrow: escrowAddress, chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days }, }, }; @@ -339,10 +481,18 @@ describe("createPaymentHeader", () => { nonce: 1, escrow: escrowAddress, chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days }, }, }; + beforeEach(() => { + vi.useFakeTimers(); + // Set a fixed time for consistent testing + vi.setSystemTime(new Date("2024-05-20T00:00:00Z")); + vi.clearAllMocks(); + }); + it("should create and encode a payment header", async () => { const result = await createPaymentHeader(buyer, 1, mockPaymentRequirements); expect(result).toBe("encoded-payment-header"); @@ -363,6 +513,7 @@ describe("createPaymentHeader", () => { nonce: mockSignedPayment.payload.voucher.nonce, escrow: mockSignedPayment.payload.voucher.escrow, chainId: mockSignedPayment.payload.voucher.chainId, + expiry: expect.any(Number), }), }), }), diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index d75bbb0fb5..9494a3f03b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -14,6 +14,8 @@ import { import { signVoucher, verifyVoucher } from "./sign"; import { encodePayment } from "./utils/paymentUtils"; +const EXPIRY_TIME = 60 * 60 * 24 * 30; // 30 days + /** * Prepares an unsigned payment header with the given sender address and payment requirements. * @@ -70,6 +72,7 @@ export function createNewVoucher( nonce: 0, escrow: extra.voucher.escrow, chainId: getNetworkId(paymentRequirements.network), + expiry: Math.floor(Date.now() / 1000) + EXPIRY_TIME, }; } @@ -87,13 +90,9 @@ export async function aggregateVoucher( const extra = DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema.parse( paymentRequirements.extra, ); - const { id, escrow, seller, valueAggregate, asset, nonce, chainId } = extra.voucher; - - // verify signature is valid and the voucher's buyer is the client - const isValid = await verifyVoucher(extra.voucher, extra.signature as Hex, buyer); - if (!isValid) { - throw new Error("Invalid voucher signature"); - } + const { id, escrow, seller, valueAggregate, asset, nonce, chainId, expiry, timestamp } = + extra.voucher; + const now = Math.floor(Date.now() / 1000); // verify previous voucher matches payment requirements if (paymentRequirements.payTo !== seller) { @@ -105,6 +104,18 @@ export async function aggregateVoucher( if (getNetworkId(paymentRequirements.network) !== chainId) { throw new Error("Invalid voucher chainId"); } + if (now > expiry) { + throw new Error("Voucher expired"); + } + if (now < timestamp) { + throw new Error("Voucher timestamp is in the future"); + } + + // verify signature is valid and the voucher's buyer is the client + const isValid = await verifyVoucher(extra.voucher, extra.signature as Hex, buyer); + if (!isValid) { + throw new Error("Invalid voucher signature"); + } return { id, @@ -114,10 +125,11 @@ export async function aggregateVoucher( BigInt(paymentRequirements.maxAmountRequired) + BigInt(valueAggregate) ).toString(), asset, - timestamp: Math.floor(Date.now() / 1000), + timestamp: now, nonce: nonce + 1, escrow, chainId, + expiry: now + EXPIRY_TIME, }; } diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts index b5ad80fe8b..9e6c5f3117 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts @@ -1,6 +1,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createSigner } from "../../../types/shared/evm"; import { signVoucher, verifyVoucher } from "./sign"; +import { privateKeyToAccount } from "viem/accounts"; const buyer = createSigner( "base-sepolia", @@ -24,10 +25,11 @@ describe("voucher signature", () => { nonce: 0, escrow: escrowAddress, chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days }; const mockVoucherSignature = - "0xabf0d28a3df19861fb7b4624d775a8e9064f3d8b285a8c26c5dfd03f445bd1c8331b706a3ac742068bbb1e08795cf0ea7c7e8cb81a715362005f7cde52e2b7e31c"; + "0x4f47e2cb1858b4d980c962bdb198c564acedec0e5d5e958431339b59130c416122faa4b8f2f34e1a5a2a3b6401cc938712abc6939ba8ab6106fb1efbb50a87e61b"; beforeEach(() => { vi.useFakeTimers(); @@ -54,4 +56,48 @@ describe("voucher signature", () => { const isValid = await verifyVoucher(mockVoucher, mockVoucherSignature, anotherBuyerAddress); expect(isValid).toBe(false); }); + + it("should sign a voucher using a LocalAccount", async () => { + const localAccount = privateKeyToAccount( + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const signature = await signVoucher(localAccount, mockVoucher); + + expect(signature.signature).toBe(mockVoucherSignature); + }); + + it("should verify a voucher signed by a LocalAccount", async () => { + const localAccount = privateKeyToAccount( + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const signature = await signVoucher(localAccount, mockVoucher); + + const isValid = await verifyVoucher(mockVoucher, signature.signature, localAccount.address); + expect(isValid).toBe(true); + }); + + it("should throw error if wallet client does not support signTypedData", async () => { + const invalidWallet = { + account: { address: buyerAddress }, + // Missing signTypedData method + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + + await expect(signVoucher(invalidWallet, mockVoucher)).rejects.toThrow( + "Invalid wallet client provided does not support signTypedData", + ); + }); + + it("should throw error if LocalAccount does not support signTypedData", async () => { + const invalidAccount = { + address: buyerAddress, + type: "local", + // Missing signTypedData method + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + + await expect(signVoucher(invalidAccount, mockVoucher)).rejects.toThrow( + "Invalid wallet client provided does not support signTypedData", + ); + }); }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts index 6777341b9b..fbb92a58b4 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts @@ -19,7 +19,8 @@ export async function signVoucher | LocalAccount, voucher: DeferredEvmPayloadVoucher, ): Promise<{ signature: Hex }> { - const { id, buyer, seller, valueAggregate, asset, timestamp, nonce, escrow, chainId } = voucher; + const { id, buyer, seller, valueAggregate, asset, timestamp, nonce, escrow, chainId, expiry } = + voucher; const data = { types: typedDataTypes, primaryType: deferredVoucherPrimaryType, @@ -39,6 +40,7 @@ export async function signVoucher { const mockVoucher = { @@ -34,6 +34,7 @@ describe("verifyPaymentRequirements", () => { nonce: 0, escrow: escrowAddress, chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days }; const mockPaymentPayload: DeferredPaymentPayload = { @@ -234,6 +235,46 @@ describe("verifyPaymentRequirements", () => { payer: buyerAddress, }); }); + + it("should return error if voucher is expired", async () => { + const now = Math.floor(Date.now() / 1000); + const invalidPayload = { + ...mockPaymentPayload, + payload: { + ...mockPaymentPayload.payload, + voucher: { + ...mockVoucher, + expiry: now - 1, // 1 second in the past + }, + }, + }; + const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_expired", + payer: buyerAddress, + }); + }); + + it("should return error if voucher timestamp is in the future", async () => { + const now = Math.floor(Date.now() / 1000); + const invalidPayload = { + ...mockPaymentPayload, + payload: { + ...mockPaymentPayload.payload, + voucher: { + ...mockVoucher, + timestamp: now + 3600, // 1 hour in the future + }, + }, + }; + const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_timestamp", + payer: buyerAddress, + }); + }); }); describe("verifyVoucherSignature", () => { @@ -253,6 +294,7 @@ describe("verifyVoucherSignature", () => { nonce: 0, escrow: escrowAddress, chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days }, }, }; @@ -304,6 +346,7 @@ describe("verifyOnchainState", () => { nonce: 0, escrow: escrowAddress, chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days }, }, }; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index 0e30e0a152..998aadbc39 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -15,6 +15,7 @@ import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; * - ✅ Verify payTo is voucher seller * - ✅ Verify voucher asset matches payment requirements * - ✅ Validates the voucher chainId matches the chain specified in the payment requirements + * - ✅ Validates the voucher expiration and timestamp dates make sense * * @param paymentPayload - The payment payload to verify * @param paymentRequirements - The payment requirements to verify @@ -114,6 +115,23 @@ export async function verifyPaymentRequirements( payer: paymentPayload.payload.voucher.buyer, }; } + + // Verify payload matches requirements: voucher expiration and timestamp + const now = Math.floor(Date.now() / 1000); + if (paymentPayload.payload.voucher.expiry < now) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_expired", + payer: paymentPayload.payload.voucher.buyer, + }; + } + if (paymentPayload.payload.voucher.timestamp > now) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_timestamp", + payer: paymentPayload.payload.voucher.buyer, + }; + } } /** @@ -200,6 +218,7 @@ export async function verifyOnchainState< nonce: BigInt(paymentPayload.payload.voucher.nonce), escrow: paymentPayload.payload.voucher.escrow as Address, chainId: BigInt(paymentPayload.payload.voucher.chainId), + expiry: BigInt(paymentPayload.payload.voucher.expiry), }, ], }); diff --git a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts index 24f40626dd..d239b1b6cf 100644 --- a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts +++ b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts @@ -125,11 +125,11 @@ export const deferredEscrowABI = [ name: "chainId", type: "uint256", }, - // { - // internalType: "uint64", - // name: "expiry", - // type: "uint64", - // }, + { + internalType: "uint64", + name: "expiry", + type: "uint64", + }, ], internalType: "struct IDeferredPaymentEscrow.Voucher", name: "voucher", diff --git a/typescript/packages/x402/src/types/shared/evm/typedData.ts b/typescript/packages/x402/src/types/shared/evm/typedData.ts index 44a5d49696..589df81dee 100644 --- a/typescript/packages/x402/src/types/shared/evm/typedData.ts +++ b/typescript/packages/x402/src/types/shared/evm/typedData.ts @@ -13,10 +13,11 @@ export const typedDataTypes = { { name: "seller", type: "address" }, { name: "valueAggregate", type: "uint256" }, { name: "asset", type: "address" }, - { name: "timestamp", type: "uint256" }, + { name: "timestamp", type: "uint64" }, { name: "nonce", type: "uint256" }, { name: "escrow", type: "address" }, { name: "chainId", type: "uint256" }, + { name: "expiry", type: "uint64" }, ], }; diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index a3c6f0c573..cf937baf03 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -20,6 +20,8 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_asset_mismatch", "invalid_deferred_evm_payload_signature", "invalid_deferred_evm_payload_no_longer_valid", + "invalid_deferred_evm_payload_voucher_expired", + "invalid_deferred_evm_payload_timestamp", ] as const; // x402DeferredEvmPayloadVoucher @@ -33,6 +35,7 @@ export const DeferredEvmPayloadVoucherSchema = z.object({ nonce: z.number().int().nonnegative(), escrow: z.string().regex(EvmAddressRegex), chainId: z.number().int().nonnegative(), + expiry: z.number().int().nonnegative(), }); export type DeferredEvmPayloadVoucher = z.infer; From 65b1cda0b04bc94536a92b8117f494c1231111c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 18 Jul 2025 16:16:23 -0300 Subject: [PATCH 025/116] fix: verify function was not returning verification results properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/schemes/deferred/evm/facilitator.ts | 15 ++++++++++++--- .../x402/src/schemes/deferred/evm/verify.ts | 10 ++++++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 8693e6ce4c..d0814548d6 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -36,13 +36,22 @@ export async function verify< paymentPayload = DeferredPaymentPayloadSchema.parse(paymentPayload); // Verify the payment payload matches the payment requirements - await verifyPaymentRequirements(paymentPayload, paymentRequirements); + const requirementsResult = await verifyPaymentRequirements(paymentPayload, paymentRequirements); + if (requirementsResult) { + return requirementsResult; + } // Verify voucher signature is valid - await verifyVoucherSignature(paymentPayload); + const signatureResult = await verifyVoucherSignature(paymentPayload); + if (signatureResult) { + return signatureResult; + } // Verify the onchain state allows the payment to be settled - await verifyOnchainState(client, paymentPayload, paymentRequirements); + const onchainResult = await verifyOnchainState(client, paymentPayload, paymentRequirements); + if (onchainResult) { + return onchainResult; + } return { isValid: true, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index 998aadbc39..679df39647 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -1,6 +1,6 @@ import { Account, Chain, Address, Hex, Transport, getAddress } from "viem"; import { DeferredPaymentPayload, DEFERRRED_SCHEME } from "../../../types/verify/schemes/deferred"; -import { PaymentRequirements } from "../../../types"; +import { PaymentRequirements, VerifyResponse } from "../../../types"; import { getNetworkId } from "../../../shared"; import { verifyVoucher } from "./sign"; import { ConnectedClient } from "../../../types/shared/evm/wallet"; @@ -24,7 +24,7 @@ import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; export async function verifyPaymentRequirements( paymentPayload: DeferredPaymentPayload, paymentRequirements: PaymentRequirements, -) { +): Promise { // Verify payload matches requirements: scheme if (paymentPayload.scheme !== DEFERRRED_SCHEME) { return { @@ -143,7 +143,9 @@ export async function verifyPaymentRequirements( * @param paymentPayload - The payment payload to verify * @returns The payment requirements if valid, otherwise an error object */ -export async function verifyVoucherSignature(paymentPayload: DeferredPaymentPayload) { +export async function verifyVoucherSignature( + paymentPayload: DeferredPaymentPayload, +): Promise { const voucherSignatureIsValid = await verifyVoucher( paymentPayload.payload.voucher, paymentPayload.payload.signature as Hex, @@ -178,7 +180,7 @@ export async function verifyOnchainState< client: ConnectedClient, paymentPayload: DeferredPaymentPayload, paymentRequirements: PaymentRequirements, -) { +): Promise { let chainId: number; try { chainId = getNetworkId(paymentRequirements.network); From 8ff7e2c68c0b4c745862990f8077a6766b788d6f Mon Sep 17 00:00:00 2001 From: Chris Whited Date: Tue, 22 Jul 2025 02:21:27 +0100 Subject: [PATCH 026/116] feat(x402-axios): implement a deferred payment scheme axiox response interceptor (#6) --- typescript/packages/x402-axios/README.md | 58 +++++- .../packages/x402-axios/src/index.test.ts | 182 +++++++++++++++++- typescript/packages/x402-axios/src/index.ts | 98 +++++++++- 3 files changed, 331 insertions(+), 7 deletions(-) diff --git a/typescript/packages/x402-axios/README.md b/typescript/packages/x402-axios/README.md index 9c9bb4b011..896e2ce4e9 100644 --- a/typescript/packages/x402-axios/README.md +++ b/typescript/packages/x402-axios/README.md @@ -10,6 +10,8 @@ npm install x402-axios ## Quick Start +### Exact Scheme + ```typescript import { createWalletClient, http } from "viem"; import { privateKeyToAccount } from "viem/accounts"; @@ -30,7 +32,37 @@ const api = withPaymentInterceptor( axios.create({ baseURL: "https://api.example.com", }), - client + client, +); + +// Make a request that may require payment +const response = await api.get("/paid-endpoint"); +console.log(response.data); +``` + +### Deferred Scheme + +```typescript +import { createWalletClient, http } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { withDeferredPaymentInterceptor } from "x402-axios"; +import axios from "axios"; +import { baseSepolia } from "viem/chains"; + +// Create a wallet client +const account = privateKeyToAccount("0xYourPrivateKey"); +const client = createWalletClient({ + account, + transport: http(), + chain: baseSepolia, +}); + +// Create an Axios instance with payment handling +const api = withDeferredPaymentInterceptor( + axios.create({ + baseURL: "https://api.example.com", + }), + client, ); // Make a request that may require payment @@ -59,6 +91,30 @@ Adds a response interceptor to an Axios instance to handle 402 Payment Required #### Returns The modified Axios instance with the payment interceptor that will: + +1. Intercept 402 responses +2. Parse the payment requirements +3. Create a payment header using the provided wallet client +4. Retry the original request with the payment header +5. Expose the X-PAYMENT-RESPONSE header in the final response + +### `withDeferredPaymentInterceptor(axiosClient, walletClient)` + +Adds a response interceptor to an Axios instance to handle 402 deferred Payment Required responses automatically. + +#### When to use + +The `withDeferredPaymentInterceptor` method should be used if the facilitator/seller being called is configured to allow for deferred/aggregated payments using a configured escrow account. The biggest difference is that the `withPaymentInterceptor` method, if a 402 response is returned, will process the payment for each request. The `withDeferredPaymentInterceptor` and `deferred` payment schemes allow the buyer (the user of this library) to make _multiple_ requests where the amount is aggregated and then paid off with **one** onchain transaciton covering all requests on a given voucher. + +#### Parameters + +- `axiosClient`: The Axios instance to add the interceptor to +- `walletClient`: The wallet client used to sign payment messages (must implement the x402 wallet interface) + +#### Returns + +The modified Axios instance with the payment interceptor that will: + 1. Intercept 402 responses 2. Parse the payment requirements 3. Create a payment header using the provided wallet client diff --git a/typescript/packages/x402-axios/src/index.test.ts b/typescript/packages/x402-axios/src/index.test.ts index 9c4eb3f87e..5dd449409a 100644 --- a/typescript/packages/x402-axios/src/index.test.ts +++ b/typescript/packages/x402-axios/src/index.test.ts @@ -6,8 +6,17 @@ import { InternalAxiosRequestConfig, } from "axios"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { evm, PaymentRequirements, ChainIdToNetwork, Signer, MultiNetworkSigner } from "x402/types"; -import { withPaymentInterceptor } from "./index"; +import { + evm, + PaymentRequirements, + ChainIdToNetwork, + Signer, + MultiNetworkSigner, + DeferredPaymentRequirements, + DEFERRRED_SCHEME, +} from "x402/types"; + +import { withDeferredPaymentInterceptor, withPaymentInterceptor } from "./index"; // Mock the createPaymentHeader function vi.mock("x402/client", () => ({ @@ -352,3 +361,172 @@ describe("withPaymentInterceptor() - SVM and MultiNetwork", () => { expect(selectPaymentRequirements).toHaveBeenCalledWith(expect.any(Array), undefined, "exact"); }); }); + +describe("withDeferredPaymentInterceptor", () => { + let mockAxiosClient: AxiosInstance; + let mockWalletClient: typeof evm.SignerWallet; + let interceptor: (error: AxiosError) => Promise; + + const escrowAddress = "0xffffff12345678901234567890123456789fffff"; + const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; + const validPaymentRequirements: Array = [ + { + scheme: "deferred", + network: "base-sepolia", + maxAmountRequired: "100000", // 0.1 USDC in base units + resource: "https://api.example.com/resource", + description: "Test payment", + mimeType: "application/json", + payTo: "0x1234567890123456789012345678901234567890", + maxTimeoutSeconds: 300, + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", // USDC on base-sepolia + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + }, + }, + ]; + + const createErrorConfig = (isRetry = false): InternalAxiosRequestConfig => + ({ + headers: new AxiosHeaders(), + url: "https://api.example.com", + method: "GET", + ...(isRetry ? { __is402Retry: true } : {}), + }) as InternalAxiosRequestConfig; + + const createAxiosError = ( + status: number, + config?: InternalAxiosRequestConfig, + data?: { accepts: PaymentRequirements[]; x402Version: number }, + ): AxiosError => { + return new AxiosError( + "Error", + "ERROR", + config, + {}, + { + status, + statusText: status === 402 ? "Payment Required" : "Not Found", + data, + headers: {}, + config: config || createErrorConfig(), + }, + ); + }; + + beforeEach(async () => { + // Reset mocks before each test + vi.resetAllMocks(); + + // Mock axios client + mockAxiosClient = { + interceptors: { + response: { + use: vi.fn(), + }, + }, + request: vi.fn(), + } as unknown as AxiosInstance; + + // Mock wallet client + mockWalletClient = { + signMessage: vi.fn(), + } as unknown as typeof evm.SignerWallet; + + // Mock payment requirements selector + const { selectPaymentRequirements } = await import("x402/client"); + (selectPaymentRequirements as ReturnType).mockImplementation( + (requirements, _) => requirements[0], + ); + + // Set up the interceptor + withDeferredPaymentInterceptor(mockAxiosClient, mockWalletClient); + interceptor = (mockAxiosClient.interceptors.response.use as ReturnType).mock + .calls[0][1]; + }); + + it("should return the axios client instance", () => { + const result = withDeferredPaymentInterceptor(mockAxiosClient, mockWalletClient); + expect(result).toBe(mockAxiosClient); + }); + + it("should set up response interceptor", () => { + expect(mockAxiosClient.interceptors.response.use).toHaveBeenCalled(); + }); + + it("should not handle non-402 errors", async () => { + const error = createAxiosError(404); + await expect(interceptor(error)).rejects.toBe(error); + }); + + it("should handle 402 errors and retry with payment header", async () => { + const paymentHeader = "payment-header-value"; + const successResponse = { data: "success" } as AxiosResponse; + + const { createPaymentHeader, selectPaymentRequirements } = await import("x402/client"); + (createPaymentHeader as ReturnType).mockResolvedValue(paymentHeader); + (selectPaymentRequirements as ReturnType).mockImplementation( + (requirements, _) => requirements[0], + ); + (mockAxiosClient.request as ReturnType).mockResolvedValue(successResponse); + + const error = createAxiosError(402, createErrorConfig(), { + accepts: validPaymentRequirements, + x402Version: 1, + }); + + const result = await interceptor(error); + + expect(result).toBe(successResponse); + expect(selectPaymentRequirements).toHaveBeenCalledWith( + validPaymentRequirements, + undefined, + DEFERRRED_SCHEME, + ); + expect(createPaymentHeader).toHaveBeenCalledWith( + mockWalletClient, + 1, + validPaymentRequirements[0], + ); + expect(mockAxiosClient.request).toHaveBeenCalledWith({ + ...error.config, + headers: new AxiosHeaders({ + "X-PAYMENT": paymentHeader, + "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", + }), + __is402Retry: true, + }); + }); + + it("should not retry if already retried", async () => { + const error = createAxiosError(402, createErrorConfig(true), { + accepts: validPaymentRequirements, + x402Version: 1, + }); + await expect(interceptor(error)).rejects.toBe(error); + }); + + it("should reject if missing request config", async () => { + const error = createAxiosError(402, undefined, { + accepts: validPaymentRequirements, + x402Version: 1, + }); + await expect(interceptor(error)).rejects.toThrow("Missing axios request configuration"); + }); + + it("should reject if payment header creation fails", async () => { + const paymentError = new Error("Payment failed"); + const { createPaymentHeader } = await import("x402/client"); + (createPaymentHeader as ReturnType).mockRejectedValue(paymentError); + + const error = createAxiosError(402, createErrorConfig(), { + accepts: validPaymentRequirements, + x402Version: 1, + }); + await expect(interceptor(error)).rejects.toBe(paymentError); + }); +}); diff --git a/typescript/packages/x402-axios/src/index.ts b/typescript/packages/x402-axios/src/index.ts index 3f6233c155..eb046e8c0e 100644 --- a/typescript/packages/x402-axios/src/index.ts +++ b/typescript/packages/x402-axios/src/index.ts @@ -1,14 +1,18 @@ import { AxiosInstance, AxiosError } from "axios"; import { - ChainIdToNetwork, - PaymentRequirements, - PaymentRequirementsSchema, Signer, MultiNetworkSigner, isMultiNetworkSigner, isSvmSignerWallet, Network, + ChainIdToNetwork, + DeferredPaymentRequirementsSchema, + DEFERRRED_SCHEME, evm, + EXACT_SCHEME, + PaymentRequirements, + PaymentRequirementsSchema, + Wallet, } from "x402/types"; import { createPaymentHeader, @@ -77,7 +81,7 @@ export function withPaymentInterceptor( ? (["solana", "solana-devnet"] as Network[]) : undefined; - const selectedPaymentRequirements = paymentRequirementsSelector(parsed, network, "exact"); + const selectedPaymentRequirements = paymentRequirementsSelector(parsed, network, EXACT_SCHEME); const paymentHeader = await createPaymentHeader( walletClient, x402Version, @@ -100,6 +104,92 @@ export function withPaymentInterceptor( return axiosClient; } +/** + * Enables the payment of APIs using the x402 deferred payment protocol. + * + * When a request receives a 402 response: + * 1. Extracts payment requirements from the response + * 2. Creates a payment header using the provided wallet client + * 3. Retries the original request with the payment header + * 4. Exposes the X-PAYMENT-RESPONSE header in the final response + * + * @param axiosClient - The Axios instance to add the interceptor to + * @param walletClient - A wallet client that can sign transactions and create payment headers + * @param paymentRequirementsSelector - A function that selects the payment requirements from the response + * @returns The modified Axios instance with the payment interceptor + * + * @example + * ```typescript + * const client = withDeferredPaymentInterceptor( + * axios.create(), + * signer + * ); + * + * // The client will automatically handle 402 responses + * const response = await client.get('https://api.example.com/premium-content'); + * ``` + */ +export function withDeferredPaymentInterceptor( + axiosClient: AxiosInstance, + walletClient: Wallet, + paymentRequirementsSelector: PaymentRequirementsSelector = selectPaymentRequirements, +) { + axiosClient.interceptors.response.use( + response => response, + async (error: AxiosError) => { + if (!error.response || error.response.status !== 402) { + return Promise.reject(error); + } + + try { + const originalConfig = error.config; + if (!originalConfig || !originalConfig.headers) { + return Promise.reject(new Error("Missing axios request configuration")); + } + + if ((originalConfig as { __is402Retry?: boolean }).__is402Retry) { + return Promise.reject(error); + } + + const { x402Version, accepts } = error.response.data as { + x402Version: number; + accepts: Array; + }; + const parsed = accepts.map(x => PaymentRequirementsSchema.parse(x)); + + const chainId = evm.isSignerWallet(walletClient) ? walletClient.chain?.id : undefined; + + const selectedPaymentRequirements = paymentRequirementsSelector( + parsed, + chainId ? ChainIdToNetwork[chainId] : undefined, + DEFERRRED_SCHEME, + ); + const selectedDeferredPaymentRequirements = DeferredPaymentRequirementsSchema.parse( + selectedPaymentRequirements, + ); + + const paymentHeader = await createPaymentHeader( + walletClient, + x402Version, + selectedDeferredPaymentRequirements, + ); + + (originalConfig as { __is402Retry?: boolean }).__is402Retry = true; + + originalConfig.headers["X-PAYMENT"] = paymentHeader; + originalConfig.headers["Access-Control-Expose-Headers"] = "X-PAYMENT-RESPONSE"; + + const paymentHeaderSignedResponse = await axiosClient.request(originalConfig); + return paymentHeaderSignedResponse; + } catch (paymentError) { + return Promise.reject(paymentError); + } + }, + ); + + return axiosClient; +} + export { decodeXPaymentResponse } from "x402/shared"; export { createSigner, type Signer, type MultiNetworkSigner } from "x402/types"; export type { Hex } from "viem"; From 7842b1d07ff1b6e94f70685a7dbe0de1b592d14a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 22 Jul 2025 10:43:35 -0300 Subject: [PATCH 027/116] fix: use latest escrow abi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/facilitator.ts | 22 +- .../x402/src/schemes/deferred/evm/index.ts | 1 + .../x402/src/schemes/deferred/evm/verify.ts | 38 +- .../src/types/shared/evm/deferredEscrowABI.ts | 1520 ++++++++++++++++- .../x402/src/types/verify/schemes/deferred.ts | 2 + .../x402/src/types/verify/x402Specs.ts | 1 - 6 files changed, 1508 insertions(+), 76 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index d0814548d6..04ca9bbbd6 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -1,4 +1,4 @@ -import { Account, Address, Chain, encodeAbiParameters, parseAbiParameters, Transport } from "viem"; +import { Account, Address, Chain, Transport, Hex } from "viem"; import { ConnectedClient, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, @@ -94,15 +94,25 @@ export async function settle( const { voucher, signature } = paymentPayload.payload; - const abiTypes = parseAbiParameters( - "(tuple(bytes32 id, address buyer, address seller, uint256 value, address asset, uint256 timestamp, uint256 nonce, address escrow, uint256 chainId) voucher, bytes signature)", - ); - const encodedData = encodeAbiParameters(abiTypes, [[voucher, signature]]); const tx = await wallet.writeContract({ address: voucher.escrow as Address, abi: deferredEscrowABI, functionName: "collect" as const, - args: [encodedData], + args: [ + { + id: voucher.id as Hex, + buyer: voucher.buyer as Address, + seller: voucher.seller as Address, + valueAggregate: BigInt(voucher.valueAggregate), + asset: voucher.asset as Address, + timestamp: BigInt(voucher.timestamp), + nonce: BigInt(voucher.nonce), + escrow: voucher.escrow as Address, + chainId: BigInt(voucher.chainId), + expiry: BigInt(voucher.expiry), + }, + signature as Hex, + ], chain: wallet.chain as Chain, }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/index.ts b/typescript/packages/x402/src/schemes/deferred/evm/index.ts index 2f115c892b..7566034e4e 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/index.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/index.ts @@ -1,3 +1,4 @@ export * from "./client"; export * from "./facilitator"; +export * from "./sign"; export * from "./utils/paymentUtils"; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index 679df39647..7ccf2ed45a 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -69,7 +69,7 @@ export async function verifyPaymentRequirements( if ( BigInt(paymentPayload.payload.voucher.valueAggregate) < BigInt(paymentRequirements.maxAmountRequired) + - BigInt(paymentRequirements.extra.voucher.valueAggregate) + BigInt(paymentRequirements.extra.voucher.valueAggregate) ) { return { isValid: false, @@ -202,13 +202,13 @@ export async function verifyOnchainState< } // Verify buyer has sufficient asset balance in the escrow contract - // We delegate the actual calculation to the escrow contract - let isVoucherCollectable: boolean; + // buyer has to cover the outstanding amount + let voucherOutstandingAmount: bigint; try { - isVoucherCollectable = await client.readContract({ + [voucherOutstandingAmount] = await client.readContract({ address: paymentPayload.payload.voucher.escrow as Address, abi: deferredEscrowABI, - functionName: "isVoucherCollectable", + functionName: "getOutstandingAndCollectableAmount", args: [ { id: paymentPayload.payload.voucher.id as Hex, @@ -227,11 +227,35 @@ export async function verifyOnchainState< } catch { return { isValid: false, - invalidReason: "insufficient_funds_contract_call_failed", + invalidReason: "invalid_deferred_evm_contract_call_failed_outstanding_amount", payer: paymentPayload.payload.voucher.buyer, }; } - if (!isVoucherCollectable) { + let buyerAccount: { + balance: bigint; + thawingAmount: bigint; + thawEndTime: bigint; + }; + try { + buyerAccount = await client.readContract({ + address: paymentPayload.payload.voucher.escrow as Address, + abi: deferredEscrowABI, + functionName: "getAccount", + args: [ + paymentPayload.payload.voucher.buyer as Address, + paymentPayload.payload.voucher.seller as Address, + paymentPayload.payload.voucher.asset as Address, + ], + }); + } catch (error) { + console.log(error); + return { + isValid: false, + invalidReason: "invalid_deferred_evm_contract_call_failed_account", + payer: paymentPayload.payload.voucher.buyer, + }; + } + if (buyerAccount.balance < voucherOutstandingAmount) { return { isValid: false, invalidReason: "insufficient_funds", diff --git a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts index d239b1b6cf..d81b05e7ae 100644 --- a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts +++ b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts @@ -1,150 +1,1546 @@ export const deferredEscrowABI = [ { - inputs: [ + type: "constructor", + inputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "DOMAIN_SEPARATOR", + inputs: [], + outputs: [ { - internalType: "bytes32", - name: "id", + name: "", type: "bytes32", + internalType: "bytes32", }, ], - name: "isCollected", + stateMutability: "view", + }, + { + type: "function", + name: "MAX_PPM", + inputs: [], outputs: [ { - internalType: "bool", name: "", - type: "bool", + type: "uint256", + internalType: "uint256", }, ], stateMutability: "view", + }, + { type: "function", + name: "MAX_THAWING_PERIOD", + inputs: [], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", }, { - name: "collect", type: "function", - stateMutability: "nonpayable", - inputs: [ + name: "UPGRADE_INTERFACE_VERSION", + inputs: [], + outputs: [ { - name: "data", - type: "bytes", + name: "", + type: "string", + internalType: "string", }, ], - outputs: [], + stateMutability: "view", }, { - inputs: [ + type: "function", + name: "VOUCHER_TYPEHASH", + inputs: [], + outputs: [ { - internalType: "address", - name: "buyer", - type: "address", + name: "", + type: "bytes32", + internalType: "bytes32", }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "cancelThaw", + inputs: [ { - internalType: "address", name: "seller", type: "address", + internalType: "address", }, { - internalType: "address", name: "asset", type: "address", + internalType: "address", }, ], - name: "accounts", - outputs: [ - { - components: [ - { - internalType: "uint256", - name: "balance", - type: "uint256", - }, - { - internalType: "uint256", - name: "thawingAmount", - type: "uint256", - }, - { - internalType: "uint64", - name: "thawEndTime", - type: "uint64", - }, - ], - internalType: "struct IDeferredPaymentEscrow.EscrowAccount", - name: "", - type: "tuple", - }, - ], - stateMutability: "view", - type: "function", + outputs: [], + stateMutability: "nonpayable", }, { + type: "function", + name: "collect", inputs: [ { + name: "voucher", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.Voucher", components: [ { - internalType: "bytes32", name: "id", type: "bytes32", + internalType: "bytes32", }, { - internalType: "address", name: "buyer", type: "address", + internalType: "address", }, { - internalType: "address", name: "seller", type: "address", + internalType: "address", }, { - internalType: "uint256", name: "valueAggregate", type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "asset", type: "address", + internalType: "address", }, { - internalType: "uint64", name: "timestamp", type: "uint64", + internalType: "uint64", }, { - internalType: "uint256", name: "nonce", type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "escrow", type: "address", + internalType: "address", }, { - internalType: "uint256", name: "chainId", type: "uint256", + internalType: "uint256", }, { - internalType: "uint64", name: "expiry", type: "uint64", + internalType: "uint64", }, ], - internalType: "struct IDeferredPaymentEscrow.Voucher", - name: "voucher", - type: "tuple", + }, + { + name: "signature", + type: "bytes", + internalType: "bytes", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "collectMany", + inputs: [ + { + name: "vouchers", + type: "tuple[]", + internalType: "struct IDeferredPaymentEscrow.SignedVoucher[]", + components: [ + { + name: "voucher", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.Voucher", + components: [ + { + name: "id", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "buyer", + type: "address", + internalType: "address", + }, + { + name: "seller", + type: "address", + internalType: "address", + }, + { + name: "valueAggregate", + type: "uint256", + internalType: "uint256", + }, + { + name: "asset", + type: "address", + internalType: "address", + }, + { + name: "timestamp", + type: "uint64", + internalType: "uint64", + }, + { + name: "nonce", + type: "uint256", + internalType: "uint256", + }, + { + name: "escrow", + type: "address", + internalType: "address", + }, + { + name: "chainId", + type: "uint256", + internalType: "uint256", + }, + { + name: "expiry", + type: "uint64", + internalType: "uint64", + }, + ], + }, + { + name: "signature", + type: "bytes", + internalType: "bytes", + }, + ], + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "deposit", + inputs: [ + { + name: "seller", + type: "address", + internalType: "address", + }, + { + name: "asset", + type: "address", + internalType: "address", + }, + { + name: "amount", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "depositMany", + inputs: [ + { + name: "asset", + type: "address", + internalType: "address", + }, + { + name: "deposits", + type: "tuple[]", + internalType: "struct IDeferredPaymentEscrow.DepositInput[]", + components: [ + { + name: "seller", + type: "address", + internalType: "address", + }, + { + name: "amount", + type: "uint256", + internalType: "uint256", + }, + ], + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "depositTo", + inputs: [ + { + name: "buyer", + type: "address", + internalType: "address", + }, + { + name: "seller", + type: "address", + internalType: "address", + }, + { + name: "asset", + type: "address", + internalType: "address", + }, + { + name: "amount", + type: "uint256", + internalType: "uint256", }, ], - name: "isVoucherCollectable", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "eip712Domain", + inputs: [], outputs: [ { - internalType: "bool", - name: "", - type: "bool", + name: "fields", + type: "bytes1", + internalType: "bytes1", + }, + { + name: "name", + type: "string", + internalType: "string", + }, + { + name: "version", + type: "string", + internalType: "string", + }, + { + name: "chainId", + type: "uint256", + internalType: "uint256", + }, + { + name: "verifyingContract", + type: "address", + internalType: "address", + }, + { + name: "salt", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "extensions", + type: "uint256[]", + internalType: "uint256[]", }, ], stateMutability: "view", + }, + { type: "function", + name: "getAccount", + inputs: [ + { + name: "buyer", + type: "address", + internalType: "address", + }, + { + name: "seller", + type: "address", + internalType: "address", + }, + { + name: "asset", + type: "address", + internalType: "address", + }, + ], + outputs: [ + { + name: "", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.EscrowAccount", + components: [ + { + name: "balance", + type: "uint256", + internalType: "uint256", + }, + { + name: "thawingAmount", + type: "uint256", + internalType: "uint256", + }, + { + name: "thawEndTime", + type: "uint64", + internalType: "uint64", + }, + ], + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getOutstandingAndCollectableAmount", + inputs: [ + { + name: "voucher", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.Voucher", + components: [ + { + name: "id", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "buyer", + type: "address", + internalType: "address", + }, + { + name: "seller", + type: "address", + internalType: "address", + }, + { + name: "valueAggregate", + type: "uint256", + internalType: "uint256", + }, + { + name: "asset", + type: "address", + internalType: "address", + }, + { + name: "timestamp", + type: "uint64", + internalType: "uint64", + }, + { + name: "nonce", + type: "uint256", + internalType: "uint256", + }, + { + name: "escrow", + type: "address", + internalType: "address", + }, + { + name: "chainId", + type: "uint256", + internalType: "uint256", + }, + { + name: "expiry", + type: "uint64", + internalType: "uint64", + }, + ], + }, + ], + outputs: [ + { + name: "outstanding", + type: "uint256", + internalType: "uint256", + }, + { + name: "collectable", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getVoucherCollected", + inputs: [ + { + name: "buyer", + type: "address", + internalType: "address", + }, + { + name: "seller", + type: "address", + internalType: "address", + }, + { + name: "voucherId", + type: "bytes32", + internalType: "bytes32", + }, + ], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "initialize", + inputs: [ + { + name: "_thawingPeriod", + type: "uint256", + internalType: "uint256", + }, + { + name: "_protocolFeePpm", + type: "uint256", + internalType: "uint256", + }, + { + name: "_protocolTreasury", + type: "address", + internalType: "address", + }, + { + name: "_owner", + type: "address", + internalType: "address", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "isSignatureValid", + inputs: [ + { + name: "voucher", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.Voucher", + components: [ + { + name: "id", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "buyer", + type: "address", + internalType: "address", + }, + { + name: "seller", + type: "address", + internalType: "address", + }, + { + name: "valueAggregate", + type: "uint256", + internalType: "uint256", + }, + { + name: "asset", + type: "address", + internalType: "address", + }, + { + name: "timestamp", + type: "uint64", + internalType: "uint64", + }, + { + name: "nonce", + type: "uint256", + internalType: "uint256", + }, + { + name: "escrow", + type: "address", + internalType: "address", + }, + { + name: "chainId", + type: "uint256", + internalType: "uint256", + }, + { + name: "expiry", + type: "uint64", + internalType: "uint64", + }, + ], + }, + { + name: "signature", + type: "bytes", + internalType: "bytes", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "owner", + inputs: [], + outputs: [ + { + name: "", + type: "address", + internalType: "address", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "pause", + inputs: [], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "paused", + inputs: [], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "protocolFeePpm", + inputs: [], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "protocolTreasury", + inputs: [], + outputs: [ + { + name: "", + type: "address", + internalType: "address", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "proxiableUUID", + inputs: [], + outputs: [ + { + name: "", + type: "bytes32", + internalType: "bytes32", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "renounceOwnership", + inputs: [], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setProtocolFee", + inputs: [ + { + name: "_protocolFeePpm", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setProtocolTreasury", + inputs: [ + { + name: "_protocolTreasury", + type: "address", + internalType: "address", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setThawingPeriod", + inputs: [ + { + name: "_thawingPeriod", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "thaw", + inputs: [ + { + name: "seller", + type: "address", + internalType: "address", + }, + { + name: "asset", + type: "address", + internalType: "address", + }, + { + name: "amount", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "thawingPeriod", + inputs: [], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "transferOwnership", + inputs: [ + { + name: "newOwner", + type: "address", + internalType: "address", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "unpause", + inputs: [], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "upgradeToAndCall", + inputs: [ + { + name: "newImplementation", + type: "address", + internalType: "address", + }, + { + name: "data", + type: "bytes", + internalType: "bytes", + }, + ], + outputs: [], + stateMutability: "payable", + }, + { + type: "function", + name: "withdraw", + inputs: [ + { + name: "seller", + type: "address", + internalType: "address", + }, + { + name: "asset", + type: "address", + internalType: "address", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "event", + name: "Deposited", + inputs: [ + { + name: "buyer", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "seller", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "asset", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "amount", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "newBalance", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "EIP712DomainChanged", + inputs: [], + anonymous: false, + }, + { + type: "event", + name: "Initialized", + inputs: [ + { + name: "version", + type: "uint64", + indexed: false, + internalType: "uint64", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "OwnershipTransferred", + inputs: [ + { + name: "previousOwner", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "newOwner", + type: "address", + indexed: true, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Paused", + inputs: [ + { + name: "account", + type: "address", + indexed: false, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "ProtocolFeeUpdated", + inputs: [ + { + name: "oldFeePpm", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "newFeePpm", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "ProtocolTreasuryUpdated", + inputs: [ + { + name: "oldTreasury", + type: "address", + indexed: false, + internalType: "address", + }, + { + name: "newTreasury", + type: "address", + indexed: false, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "ThawCancelled", + inputs: [ + { + name: "buyer", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "seller", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "asset", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "amount", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "ThawInitiated", + inputs: [ + { + name: "buyer", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "seller", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "asset", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "newThawingAmount", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "previousThawingAmount", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "newThawEndTime", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "previousThawEndTime", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "ThawingPeriodUpdated", + inputs: [ + { + name: "oldPeriod", + type: "uint64", + indexed: false, + internalType: "uint64", + }, + { + name: "newPeriod", + type: "uint64", + indexed: false, + internalType: "uint64", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Unpaused", + inputs: [ + { + name: "account", + type: "address", + indexed: false, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Upgraded", + inputs: [ + { + name: "implementation", + type: "address", + indexed: true, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "VoucherAlreadyCollected", + inputs: [ + { + name: "voucherId", + type: "bytes32", + indexed: true, + internalType: "bytes32", + }, + { + name: "buyer", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "seller", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "asset", + type: "address", + indexed: false, + internalType: "address", + }, + { + name: "totalCollected", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "VoucherCollected", + inputs: [ + { + name: "voucherId", + type: "bytes32", + indexed: true, + internalType: "bytes32", + }, + { + name: "buyer", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "seller", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "asset", + type: "address", + indexed: false, + internalType: "address", + }, + { + name: "amount", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "totalCollected", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "protocolFee", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "VoucherNoCollectableBalance", + inputs: [ + { + name: "voucherId", + type: "bytes32", + indexed: true, + internalType: "bytes32", + }, + { + name: "buyer", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "seller", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "asset", + type: "address", + indexed: false, + internalType: "address", + }, + { + name: "outstanding", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "alreadyCollected", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Withdrawn", + inputs: [ + { + name: "buyer", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "seller", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "asset", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "amount", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "remainingBalance", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "error", + name: "AddressEmptyCode", + inputs: [ + { + name: "target", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "ERC1967InvalidImplementation", + inputs: [ + { + name: "implementation", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "ERC1967NonPayable", + inputs: [], + }, + { + type: "error", + name: "EnforcedPause", + inputs: [], + }, + { + type: "error", + name: "ExpectedPause", + inputs: [], + }, + { + type: "error", + name: "FailedCall", + inputs: [], + }, + { + type: "error", + name: "InsufficientBalance", + inputs: [ + { + name: "available", + type: "uint256", + internalType: "uint256", + }, + { + name: "requested", + type: "uint256", + internalType: "uint256", + }, + ], + }, + { + type: "error", + name: "InvalidAddress", + inputs: [ + { + name: "provided", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "InvalidAmount", + inputs: [ + { + name: "provided", + type: "uint256", + internalType: "uint256", + }, + ], + }, + { + type: "error", + name: "InvalidAsset", + inputs: [ + { + name: "provided", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "InvalidChainId", + inputs: [ + { + name: "provided", + type: "uint256", + internalType: "uint256", + }, + { + name: "expected", + type: "uint256", + internalType: "uint256", + }, + ], + }, + { + type: "error", + name: "InvalidEscrow", + inputs: [ + { + name: "provided", + type: "address", + internalType: "address", + }, + { + name: "expected", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "InvalidInitialization", + inputs: [], + }, + { + type: "error", + name: "InvalidProtocolFee", + inputs: [ + { + name: "provided", + type: "uint256", + internalType: "uint256", + }, + { + name: "maximum", + type: "uint256", + internalType: "uint256", + }, + ], + }, + { + type: "error", + name: "InvalidSignature", + inputs: [ + { + name: "voucherId", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "buyer", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "InvalidThawingPeriod", + inputs: [ + { + name: "provided", + type: "uint256", + internalType: "uint256", + }, + { + name: "maximum", + type: "uint256", + internalType: "uint256", + }, + ], + }, + { + type: "error", + name: "NoDepositsProvided", + inputs: [], + }, + { + type: "error", + name: "NoThawingInProgress", + inputs: [ + { + name: "buyer", + type: "address", + internalType: "address", + }, + { + name: "seller", + type: "address", + internalType: "address", + }, + { + name: "asset", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "NoVouchersProvided", + inputs: [], + }, + { + type: "error", + name: "NotInitializing", + inputs: [], + }, + { + type: "error", + name: "OwnableInvalidOwner", + inputs: [ + { + name: "owner", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "OwnableUnauthorizedAccount", + inputs: [ + { + name: "account", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "ReentrancyGuardReentrantCall", + inputs: [], + }, + { + type: "error", + name: "SafeERC20FailedOperation", + inputs: [ + { + name: "token", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "ThawingPeriodNotCompleted", + inputs: [ + { + name: "currentTime", + type: "uint256", + internalType: "uint256", + }, + { + name: "thawEndTime", + type: "uint256", + internalType: "uint256", + }, + ], + }, + { + type: "error", + name: "UUPSUnauthorizedCallContext", + inputs: [], + }, + { + type: "error", + name: "UUPSUnsupportedProxiableUUID", + inputs: [ + { + name: "slot", + type: "bytes32", + internalType: "bytes32", + }, + ], + }, + { + type: "error", + name: "VoucherExpired", + inputs: [ + { + name: "voucherId", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "currentTime", + type: "uint256", + internalType: "uint256", + }, + { + name: "expiry", + type: "uint256", + internalType: "uint256", + }, + ], }, ] as const; diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index cf937baf03..d7be33da39 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -22,6 +22,8 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_no_longer_valid", "invalid_deferred_evm_payload_voucher_expired", "invalid_deferred_evm_payload_timestamp", + "invalid_deferred_evm_contract_call_failed_outstanding_amount", + "invalid_deferred_evm_contract_call_failed_account", ] as const; // x402DeferredEvmPayloadVoucher diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index 2375fa35b4..1ca52351fc 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -22,7 +22,6 @@ import { EvmOrSvmAddress } from ".."; export const schemes = [EXACT_SCHEME, DEFERRRED_SCHEME] as const; export const ErrorReasons = [ "insufficient_funds", - "insufficient_funds_contract_call_failed", "invalid_network", "invalid_network_unsupported", "invalid_client_network", From 71a87a3161a98958de4a16f7d9f61364caaddba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 22 Jul 2025 10:44:34 -0300 Subject: [PATCH 028/116] chore: lint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/schemes/deferred/evm/verify.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index 7ccf2ed45a..2a30ce228a 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -69,7 +69,7 @@ export async function verifyPaymentRequirements( if ( BigInt(paymentPayload.payload.voucher.valueAggregate) < BigInt(paymentRequirements.maxAmountRequired) + - BigInt(paymentRequirements.extra.voucher.valueAggregate) + BigInt(paymentRequirements.extra.voucher.valueAggregate) ) { return { isValid: false, From 436f12a9ca55e7309c2f7be54feb42ae2ba39df1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 22 Jul 2025 11:10:46 -0300 Subject: [PATCH 029/116] fix: voucher signature structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/schemes/deferred/evm/sign.ts | 4 ++-- typescript/packages/x402/src/types/shared/evm/typedData.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts index fbb92a58b4..df1e293835 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts @@ -25,7 +25,7 @@ export async function signVoucher Date: Tue, 22 Jul 2025 11:11:03 -0300 Subject: [PATCH 030/116] test: amend tests due to latest changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/client.test.ts | 6 ++-- .../src/schemes/deferred/evm/sign.test.ts | 2 +- .../src/schemes/deferred/evm/verify.test.ts | 30 +++++++++++++++---- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts index e3b7df7cd5..a226713a23 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -209,7 +209,7 @@ describe("preparePaymentHeader: aggregated voucher", () => { extra: { type: "aggregation", signature: - "0x4f47e2cb1858b4d980c962bdb198c564acedec0e5d5e958431339b59130c416122faa4b8f2f34e1a5a2a3b6401cc938712abc6939ba8ab6106fb1efbb50a87e61b", + "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c", voucher: { id: voucherId, buyer: buyerAddress, @@ -403,7 +403,7 @@ describe("signPaymentHeader", () => { }, }; const mockVoucherSignature = - "0x4f47e2cb1858b4d980c962bdb198c564acedec0e5d5e958431339b59130c416122faa4b8f2f34e1a5a2a3b6401cc938712abc6939ba8ab6106fb1efbb50a87e61b"; + "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c"; it("should sign the payment header and return a complete payload", async () => { const signedPaymentPayload = await signPaymentHeader(buyer, mockUnsignedHeader); @@ -448,7 +448,7 @@ describe("createPaymentHeader", () => { extra: { type: "aggregation", signature: - "0x4f47e2cb1858b4d980c962bdb198c564acedec0e5d5e958431339b59130c416122faa4b8f2f34e1a5a2a3b6401cc938712abc6939ba8ab6106fb1efbb50a87e61b", + "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c", voucher: { id: voucherId, buyer: buyerAddress, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts index 9e6c5f3117..e9f8fb2dba 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts @@ -29,7 +29,7 @@ describe("voucher signature", () => { }; const mockVoucherSignature = - "0x4f47e2cb1858b4d980c962bdb198c564acedec0e5d5e958431339b59130c416122faa4b8f2f34e1a5a2a3b6401cc938712abc6939ba8ab6106fb1efbb50a87e61b"; + "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c"; beforeEach(() => { vi.useFakeTimers(); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts index e5775b60b6..5652237017 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts @@ -21,7 +21,7 @@ const escrowAddress = "0xffffff12345678901234567890123456789fffff"; const assetAddress = "0x1111111111111111111111111111111111111111"; const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; const voucherSignature = - "0x4f47e2cb1858b4d980c962bdb198c564acedec0e5d5e958431339b59130c416122faa4b8f2f34e1a5a2a3b6401cc938712abc6939ba8ab6106fb1efbb50a87e61b"; + "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c"; describe("verifyPaymentRequirements", () => { const mockVoucher = { @@ -386,7 +386,9 @@ describe("verifyOnchainState", () => { }); it("should return undefined for valid onchain state", async () => { - vi.mocked(mockClient.readContract).mockResolvedValueOnce(true); + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce([BigInt(1_000_000)]) + .mockResolvedValueOnce({ balance: BigInt(10_000_000) }); const result = await verifyOnchainState( mockClient, @@ -426,7 +428,7 @@ describe("verifyOnchainState", () => { }); }); - it("should return error if balance check fails", async () => { + it("should return error if outstanding amount check fails", async () => { vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); const result = await verifyOnchainState( mockClient, @@ -435,13 +437,31 @@ describe("verifyOnchainState", () => { ); expect(result).toEqual({ isValid: false, - invalidReason: "insufficient_funds_contract_call_failed", + invalidReason: "invalid_deferred_evm_contract_call_failed_outstanding_amount", + payer: buyerAddress, + }); + }); + + it("should return error if balance check fails", async () => { + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce([BigInt(1_000_000)]) + .mockRejectedValueOnce(new Error("Contract call failed")); + const result = await verifyOnchainState( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_contract_call_failed_account", payer: buyerAddress, }); }); it("should return error if insufficient balance", async () => { - vi.mocked(mockClient.readContract).mockResolvedValueOnce(false); + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce([BigInt(1_000_000)]) + .mockResolvedValueOnce({ balance: BigInt(100_000) }); const result = await verifyOnchainState( mockClient, From 443548a2b0c2c3534107d9bdccccce80229bbb3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 30 Jul 2025 09:23:28 -0300 Subject: [PATCH 031/116] wip: resource server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- examples/typescript/pnpm-lock.yaml | 545 ++++++++++++++++-- examples/typescript/servers/express/client.ts | 25 + .../typescript/servers/express/deferred.ts | 363 ++++++++++++ .../typescript/servers/express/package.json | 6 +- 4 files changed, 896 insertions(+), 43 deletions(-) create mode 100644 examples/typescript/servers/express/client.ts create mode 100644 examples/typescript/servers/express/deferred.ts diff --git a/examples/typescript/pnpm-lock.yaml b/examples/typescript/pnpm-lock.yaml index 9c9e999cdf..0395e10fb4 100644 --- a/examples/typescript/pnpm-lock.yaml +++ b/examples/typescript/pnpm-lock.yaml @@ -956,13 +956,13 @@ importers: dependencies: '@coinbase/onchainkit': specifier: latest - version: 1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76) + version: 1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11) '@coinbase/x402': specifier: latest version: 0.6.4(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) '@farcaster/frame-sdk': specifier: ^0.0.60 - version: 0.0.60(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 0.0.60(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@tanstack/react-query': specifier: ^5 version: 5.90.2(react@19.1.1) @@ -971,7 +971,7 @@ importers: version: 1.35.4 '@wagmi/core': specifier: ^2.17.1 - version: 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + version: 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) next: specifier: ^15.3.4 version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -986,10 +986,10 @@ importers: version: 2.6.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) viem: specifier: ^2.27.2 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) wagmi: specifier: ^2.14.11 - version: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + version: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) x402-fetch: specifier: ^0.4.1 version: 0.4.2(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) @@ -1187,7 +1187,7 @@ importers: dependencies: '@coinbase/onchainkit': specifier: latest - version: 1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11) + version: 1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11) '@tanstack/react-query': specifier: ^5 version: 5.90.2(react@19.1.1) @@ -1404,12 +1404,18 @@ importers: servers/express: dependencies: + axios: + specifier: ^1.11.0 + version: 1.12.2 dotenv: specifier: ^16.4.7 version: 16.6.1 express: specifier: ^4.18.2 version: 4.21.2 + x402-axios: + specifier: workspace:* + version: link:../../../../typescript/packages/x402-axios x402-express: specifier: workspace:* version: link:../../../../typescript/packages/x402-express @@ -10990,10 +10996,10 @@ snapshots: - utf-8-validate - zod - '@coinbase/onchainkit@1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)': + '@coinbase/onchainkit@1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11)': dependencies: - '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) '@floating-ui/react': 0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -11001,7 +11007,7 @@ snapshots: '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@tanstack/react-query': 5.90.2(react@19.1.1) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) clsx: 2.1.1 graphql: 16.11.0 graphql-request: 6.1.0(encoding@0.1.13)(graphql@16.11.0) @@ -11010,8 +11016,8 @@ snapshots: react-dom: 19.1.1(react@19.1.1) tailwind-merge: 3.3.1 usehooks-ts: 3.1.1(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) transitivePeerDependencies: - '@tanstack/query-core' - '@types/react' @@ -11024,7 +11030,7 @@ snapshots: - utf-8-validate - zod - '@coinbase/onchainkit@1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11)': + '@coinbase/onchainkit@1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11)': dependencies: '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) @@ -11612,13 +11618,13 @@ snapshots: - typescript - utf-8-validate - '@farcaster/frame-sdk@0.0.60(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@farcaster/frame-sdk@0.0.60(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@farcaster/frame-core': 0.1.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) '@farcaster/quick-auth': 0.0.5(typescript@5.9.2) comlink: 4.4.2 eventemitter3: 5.0.1 - ox: 0.4.4(typescript@5.9.2)(zod@3.25.76) + ox: 0.4.4(typescript@5.9.2)(zod@4.1.11) transitivePeerDependencies: - bufferutil - encoding @@ -13572,11 +13578,46 @@ snapshots: - utf-8-validate - zod + '@reown/appkit-controllers@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + 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-controllers@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) transitivePeerDependencies: @@ -13678,6 +13719,42 @@ snapshots: - utf-8-validate - zod + '@reown/appkit-pay@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) + lit: 3.3.0 + valtio: 1.13.2(@types/react@19.1.13)(react@19.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' + - '@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.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) @@ -13791,6 +13868,43 @@ snapshots: - valtio - zod + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + 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-scaffold-ui@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) @@ -13900,6 +14014,41 @@ snapshots: - utf-8-validate - zod + '@reown/appkit-ui@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + 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-ui@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) @@ -14008,6 +14157,44 @@ snapshots: - utf-8-validate - zod + '@reown/appkit-utils@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@walletconnect/logger': 2.1.2 + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + 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.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) @@ -14015,7 +14202,7 @@ snapshots: '@reown/appkit-polyfills': 1.7.8 '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) transitivePeerDependencies: @@ -14138,6 +14325,49 @@ snapshots: - utf-8-validate - zod + '@reown/appkit@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-pay': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + bs58: 6.0.0 + valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + 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@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) @@ -14149,7 +14379,7 @@ snapshots: '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) bs58: 6.0.0 valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) @@ -15719,6 +15949,100 @@ snapshots: - wagmi - zod + '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@3.25.76)': + dependencies: + '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + cbw-sdk: '@coinbase/wallet-sdk@3.9.3' + porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + optionalDependencies: + typescript: 5.9.2 + 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' + - '@tanstack/react-query' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - immer + - ioredis + - react + - supports-color + - uploadthing + - use-sync-external-store + - utf-8-validate + - wagmi + - zod + + '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11)': + dependencies: + '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11) + '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + cbw-sdk: '@coinbase/wallet-sdk@3.9.3' + porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11)) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + optionalDependencies: + typescript: 5.9.2 + 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' + - '@tanstack/react-query' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - immer + - ioredis + - react + - supports-color + - uploadthing + - use-sync-external-store + - utf-8-validate + - wagmi + - zod + '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11)': dependencies: '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11) @@ -15917,7 +16241,7 @@ snapshots: - utf-8-validate - zod - '@walletconnect/core@2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/core@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-provider': 1.0.14 @@ -15931,7 +16255,7 @@ snapshots: '@walletconnect/safe-json': 1.0.2 '@walletconnect/time': 1.0.2 '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 @@ -16005,7 +16329,7 @@ snapshots: - utf-8-validate - zod - '@walletconnect/core@2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/core@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-provider': 1.0.14 @@ -16019,7 +16343,7 @@ snapshots: '@walletconnect/safe-json': 1.0.2 '@walletconnect/time': 1.0.2 '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 @@ -16094,6 +16418,47 @@ snapshots: - utf-8-validate - zod + '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + dependencies: + '@reown/appkit': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) + '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + 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/ethereum-provider@2.21.1(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@reown/appkit': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) @@ -16102,10 +16467,10 @@ snapshots: '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) - '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) - '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -16305,16 +16670,16 @@ snapshots: - utf-8-validate - zod - '@walletconnect/sign-client@2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/sign-client@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: - '@walletconnect/core': 2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/core': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@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.0(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -16377,16 +16742,16 @@ snapshots: - utf-8-validate - zod - '@walletconnect/sign-client@2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/sign-client@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: - '@walletconnect/core': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/core': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@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.1(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -16515,7 +16880,7 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/universal-provider@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) @@ -16524,9 +16889,9 @@ snapshots: '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/sign-client': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -16595,7 +16960,7 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/universal-provider@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) @@ -16604,9 +16969,9 @@ snapshots: '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -16679,7 +17044,7 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.21.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/utils@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 @@ -16767,7 +17132,7 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.21.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/utils@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 @@ -20608,6 +20973,26 @@ snapshots: - immer - use-sync-external-store + porto@0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11)): + dependencies: + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + hono: 4.9.8 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.9.2) + ox: 0.9.7(typescript@5.9.2)(zod@4.1.11) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + zod: 4.1.11 + zustand: 5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + optionalDependencies: + '@tanstack/react-query': 5.90.2(react@19.1.1) + react: 19.1.1 + typescript: 5.9.2 + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store + porto@0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@wagmi/core@2.21.1(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76)): dependencies: '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) @@ -22424,6 +22809,84 @@ snapshots: - utf-8-validate - zod + wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76): + dependencies: + '@tanstack/react-query': 5.90.2(react@19.1.1) + '@wagmi/connectors': 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@3.25.76) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + react: 19.1.1 + use-sync-external-store: 1.4.0(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + optionalDependencies: + typescript: 5.9.2 + 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' + - '@tanstack/query-core' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - immer + - ioredis + - supports-color + - uploadthing + - utf-8-validate + - zod + + wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11): + dependencies: + '@tanstack/react-query': 5.90.2(react@19.1.1) + '@wagmi/connectors': 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11) + '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + react: 19.1.1 + use-sync-external-store: 1.4.0(react@19.1.1) + viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + optionalDependencies: + typescript: 5.9.2 + 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' + - '@tanstack/query-core' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - immer + - ioredis + - supports-color + - uploadthing + - utf-8-validate + - zod + wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11): dependencies: '@tanstack/react-query': 5.90.2(react@19.1.1) @@ -22771,7 +23234,7 @@ snapshots: x402@0.4.3(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -22813,7 +23276,7 @@ snapshots: '@solana/kit': 2.3.0(typescript@5.9.2) '@solana/transaction-confirmation': 2.3.0(typescript@5.9.2) viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' diff --git a/examples/typescript/servers/express/client.ts b/examples/typescript/servers/express/client.ts new file mode 100644 index 0000000000..522fdae86a --- /dev/null +++ b/examples/typescript/servers/express/client.ts @@ -0,0 +1,25 @@ +import { createWalletClient, http } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { withDeferredPaymentInterceptor } from "x402-axios"; +import axios from "axios"; +import { baseSepolia } from "viem/chains"; + +// Create a wallet client +const account = privateKeyToAccount( + "0x7492e7f8c59dd58f73a500c7d38b763cc525273cfb195fdc5862e495b257b41a", +); +const client = createWalletClient({ + account, + transport: http(), + chain: baseSepolia, +}); + +// Create an Axios instance with payment handling +const api = withDeferredPaymentInterceptor( + axios.create({ baseURL: "http://localhost:3002" }), + client, +); + +// Make a request that may require payment +const response = await api.get("/premium-joke"); +console.log(response.data); diff --git a/examples/typescript/servers/express/deferred.ts b/examples/typescript/servers/express/deferred.ts new file mode 100644 index 0000000000..8da31e31b9 --- /dev/null +++ b/examples/typescript/servers/express/deferred.ts @@ -0,0 +1,363 @@ +#!/usr/bin/env node + +/** + * X402 Deferred Payment Joke Server - Simplified Example + * + * This is a minimal Express server demonstrating X402 deferred payment integration + * using the standardized @project-a2ap/gateway client package. + */ + +import express from "express"; +import { GatewayClient } from "@x402/gateway/client"; +import { deferred } from "x402/schemes"; + +// Configuration +const PORT = parseInt(process.env.PORT || "3002"); +const GATEWAY_URL = process.env.GATEWAY_URL || "http://localhost:3001"; +const PAYMENT_PRICE = process.env.PAYMENT_PRICE || "0.00001"; +const PAYMENT_NETWORK = (process.env.PAYMENT_NETWORK as "base-sepolia" | "base") || "base-sepolia"; +const PAYMENT_SELLER = process.env.PAYMENT_SELLER || "0xC93d37AD45c907eE1b27a02b2E1bd823BA9D379C"; + +// Initialize Gateway client +const gatewayClient = new GatewayClient({ + baseUrl: GATEWAY_URL, +}); + +// Simple joke collections +const FREE_JOKES = [ + "Why don't scientists trust atoms? Because they make up everything!", + "Why did the scarecrow win an award? He was outstanding in his field!", + "Why don't eggs tell jokes? They'd crack each other up!", + "What do you call a fake noodle? An impasta!", + "Why did the math book look so sad? Because it was full of problems!", +]; + +const PREMIUM_JOKES = [ + "Why don't programmers like nature? It has too many bugs!", + "How many programmers does it take to change a light bulb? None – that's a hardware problem!", + "Why do Java developers wear glasses? Because they don't see sharp!", + "What's a computer's favorite beat? An algo-rhythm!", + "Why did the developer go broke? Because he used up all his cache!", + "How do you comfort a JavaScript bug? You console it!", + "What do you call a programmer from Finland? Nerdic!", + "Why do programmers prefer dark mode? Because light attracts bugs!", +]; + +// Helper functions +/** + * Get a random joke from the list + * + * @param jokes - The list of jokes to choose from + * @returns A random joke from the list + */ +function getRandomJoke(jokes: string[]): string { + return jokes[Math.floor(Math.random() * jokes.length)]; +} + +/** + * Convert a price in dollars to atomic units + * + * @param priceInDollars - The price in dollars + * @returns The price in atomic units + */ +function priceToAtomicUnits(priceInDollars: string): string { + const priceFloat = parseFloat(priceInDollars); + const atomicUnits = Math.floor(priceFloat * 1000000); // USDC has 6 decimals + return atomicUnits.toString(); +} + +// Create Express app +const app = express(); + +// Basic middleware +app.use(express.json()); +app.use(express.urlencoded({ extended: true })); + +// Add request logging +app.use((req, res, next) => { + console.log(`${new Date().toISOString()} ${req.method} ${req.path}`); + next(); +}); + +// Routes + +// Root endpoint - Server info +app.get("/", (req, res) => { + res.json({ + name: "X402 Deferred Payment Joke Server", + version: "1.0.0", + description: "A simple example demonstrating X402 deferred payments", + endpoints: { + freeJoke: "/free-joke", + premiumJoke: "/premium-joke", + health: "/health", + }, + payment: { + network: PAYMENT_NETWORK, + price: `$${PAYMENT_PRICE}`, + seller: PAYMENT_SELLER, + }, + }); +}); + +// Health check +app.get("/health", (_req, res) => { + void (async () => { + try { + // Simple fetch to check gateway connectivity + const response = await fetch(`${GATEWAY_URL}/health`, { + method: "GET", + signal: AbortSignal.timeout(5000), + }); + + const gatewayHealthy = response.ok; + + res.status(gatewayHealthy ? 200 : 503).json({ + status: gatewayHealthy ? "healthy" : "unhealthy", + gateway: { + url: GATEWAY_URL, + status: gatewayHealthy ? "connected" : "disconnected", + }, + timestamp: new Date().toISOString(), + }); + } catch (error: unknown) { + res.status(503).json({ + status: "unhealthy", + gateway: { + url: GATEWAY_URL, + status: "error", + error: error instanceof Error ? error.message : "Unknown error", + }, + timestamp: new Date().toISOString(), + }); + } + })(); +}); + +// Free joke endpoint +app.get("/free-joke", (req, res) => { + const joke = getRandomJoke(FREE_JOKES); + res.json({ + joke, + type: "free", + timestamp: new Date().toISOString(), + }); +}); + +// Premium joke endpoint (requires payment) +app.get("/premium-joke", (req, res) => { + void (async () => { + try { + const paymentHeader = req.header("X-Payment"); + + // Check for payment header + if (!paymentHeader) { + return res.status(402).json({ + error: "Payment required", + code: "PAYMENT_REQUIRED", + x402Version: 1, + accepts: [ + { + scheme: "deferred", + network: PAYMENT_NETWORK, + maxAmountRequired: priceToAtomicUnits(PAYMENT_PRICE), + resource: `${req.protocol}://${req.get("host")}${req.originalUrl}`, + description: `Premium joke access - $${PAYMENT_PRICE}`, + mimeType: "application/json", + payTo: PAYMENT_SELLER, + maxTimeoutSeconds: 300, + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + extra: { + type: "new", + voucher: { + id: `0x${Date.now().toString(16)}${Math.random().toString(16).slice(2)}`.padEnd( + 66, + "0", + ), + escrow: "0x1a9ea876cfe472514967d2e5cf326fb49dc68559", // TODO: Update with real escrow + }, + }, + }, + ], + timestamp: new Date().toISOString(), + }); + } + + // Decode payment + let decodedPayment; + try { + decodedPayment = deferred.evm.decodePayment(paymentHeader); + } catch (error) { + return res.status(400).json({ + error: "Invalid payment format", + code: "INVALID_PAYMENT", + details: error instanceof Error ? error.message : "Payment decoding failed", + timestamp: new Date().toISOString(), + }); + } + + // Verify scheme + if (decodedPayment.scheme !== "deferred") { + return res.status(400).json({ + error: `Invalid payment scheme. Expected 'deferred', got '${decodedPayment.scheme}'`, + code: "INVALID_SCHEME", + timestamp: new Date().toISOString(), + }); + } + + // Create payment requirements for Gateway verification + const paymentRequirements = { + scheme: "deferred" as const, + network: PAYMENT_NETWORK, + maxAmountRequired: priceToAtomicUnits(PAYMENT_PRICE), + resource: `${req.protocol}://${req.get("host")}${req.originalUrl}`, + description: `Premium joke access - $${PAYMENT_PRICE}`, + mimeType: "application/json", + payTo: PAYMENT_SELLER, + maxTimeoutSeconds: 300, + asset: + PAYMENT_NETWORK === "base-sepolia" + ? "0x036CbD53842c5426634e7929541eC2318f3dCF7e" + : "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + extra: { + type: "new" as const, + voucher: { + id: `0x${Date.now().toString(16)}${Math.random().toString(16).slice(2)}`.padEnd( + 66, + "0", + ), + escrow: "0x0000000000000000000000000000000000000000", + }, + }, + }; + + // Verify payment with Gateway + console.log("Verifying payment with Gateway..."); + const verificationResult = await gatewayClient.verify(decodedPayment, paymentRequirements); + + if (!verificationResult.valid) { + return res.status(402).json({ + error: "Payment verification failed", + code: "VERIFICATION_FAILED", + details: verificationResult.error, + timestamp: new Date().toISOString(), + }); + } + + // Payment verified successfully + console.log("Payment verified successfully:", { + isNewVoucher: verificationResult.gatewayDetails?.isNewVoucher, + details: + typeof verificationResult.gatewayDetails?.details === "string" + ? verificationResult.gatewayDetails?.details + : JSON.stringify(verificationResult.gatewayDetails?.details) || "No details provided", + }); + + // Return premium joke + const joke = getRandomJoke(PREMIUM_JOKES); + res.json({ + joke, + type: "premium", + price: `$${PAYMENT_PRICE}`, + payment: { + verified: true, + isNewVoucher: verificationResult.gatewayDetails?.isNewVoucher, + }, + timestamp: new Date().toISOString(), + }); + } catch (error: unknown) { + console.error("Premium joke endpoint error:", error); + res.status(500).json({ + error: "Internal server error", + code: "INTERNAL_ERROR", + details: error instanceof Error ? error.message : "Unknown error", + timestamp: new Date().toISOString(), + }); + } + })(); +}); + +// 404 handler +app.use((req, res) => { + res.status(404).json({ + error: "Not found", + code: "NOT_FOUND", + path: req.path, + timestamp: new Date().toISOString(), + }); +}); + +// Error handler +app.use((error: Error, req: express.Request, res: express.Response) => { + console.error("Unhandled error:", error); + res.status(500).json({ + error: "Internal server error", + code: "INTERNAL_ERROR", + timestamp: new Date().toISOString(), + }); +}); + +// Start server +/** + * Start the server + */ +async function startServer() { + try { + // Check Gateway connection on startup + console.log("🔍 Checking Gateway connection..."); + try { + const response = await fetch(`${GATEWAY_URL}/health`, { + method: "GET", + signal: AbortSignal.timeout(5000), + }); + if (response.ok) { + console.log("✅ Gateway connection verified"); + } else { + console.log("⚠️ Gateway connection failed - server will still start"); + } + } catch { + console.log("⚠️ Gateway connection error - server will still start"); + } + + // Start Express server + const server = app.listen(PORT, () => { + console.log(`🎭 X402 Deferred Payment Joke Server started`); + console.log(`📍 Server: http://localhost:${PORT}`); + console.log(`🌐 Network: ${PAYMENT_NETWORK}`); + console.log(`💰 Price: $${PAYMENT_PRICE}`); + console.log(`🔗 Gateway: ${GATEWAY_URL}`); + console.log(`🔗 Seller: ${PAYMENT_SELLER}`); + console.log(""); + console.log("Available endpoints:"); + console.log(` GET / - Server info`); + console.log(` GET /health - Health check`); + console.log(` GET /free-joke - Get a free joke`); + console.log(` GET /premium-joke - Get a premium joke (requires X-Payment header)`); + console.log(""); + console.log(`Try: curl http://localhost:${PORT}/free-joke`); + }); + + // Graceful shutdown + const gracefulShutdown = (signal: string) => { + console.log(`\n🛑 Received ${signal}. Shutting down gracefully...`); + server.close(() => { + console.log("✅ Server closed"); + process.exit(0); + }); + }; + + process.on("SIGTERM", () => gracefulShutdown("SIGTERM")); + process.on("SIGINT", () => gracefulShutdown("SIGINT")); + } catch (error) { + console.error("❌ Failed to start server:", error); + process.exit(1); + } +} + +// Start server if this file is run directly +if (import.meta.url === `file://${process.argv[1]}`) { + void startServer(); +} + +// Export for testing +export { app, startServer }; diff --git a/examples/typescript/servers/express/package.json b/examples/typescript/servers/express/package.json index 0e4cd41af8..10f7a9e41f 100644 --- a/examples/typescript/servers/express/package.json +++ b/examples/typescript/servers/express/package.json @@ -10,9 +10,11 @@ "lint:check": "eslint . --ext .ts" }, "dependencies": { + "axios": "^1.11.0", "dotenv": "^16.4.7", "express": "^4.18.2", - "x402-express": "workspace:*" + "x402-express": "workspace:*", + "x402-axios": "workspace:*" }, "devDependencies": { "@eslint/js": "^9.24.0", @@ -28,4 +30,4 @@ "tsx": "^4.7.0", "typescript": "^5.3.0" } -} +} \ No newline at end of file From 89ccd96dbd79aa7c532acca771bb3d93cb01c171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 31 Jul 2025 09:08:51 -0300 Subject: [PATCH 032/116] feat: add X-PAYMENT-BUYER header logic to fetch client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-fetch/src/index.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/typescript/packages/x402-fetch/src/index.ts b/typescript/packages/x402-fetch/src/index.ts index b615e34d36..174e2bb6f6 100644 --- a/typescript/packages/x402-fetch/src/index.ts +++ b/typescript/packages/x402-fetch/src/index.ts @@ -1,3 +1,4 @@ +import { Client, LocalAccount } from "viem"; import { createPaymentHeader, PaymentRequirementsSelector, @@ -165,6 +166,19 @@ export function wrapFetchWithDeferredPayment( paymentRequirementsSelector: PaymentRequirementsSelector = selectPaymentRequirements, ) { return async (input: RequestInfo, init?: RequestInit) => { + // Add header to the initial request to identify the buyer + const buyer = + (walletClient as LocalAccount).address || (walletClient as Client).account?.address; + if (buyer) { + init = { + ...init, + headers: { + ...(init?.headers || {}), + "X-PAYMENT-BUYER": buyer, + }, + }; + } + const response = await fetch(input, init); if (response.status !== 402) { From c46bafdc8a3d0d94bacb6c4c31267cb7a5c8d378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 31 Jul 2025 09:17:45 -0300 Subject: [PATCH 033/116] feat: add deferred payment middleware to express package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-express/src/index.ts | 176 +++++++++++++++++- 1 file changed, 173 insertions(+), 3 deletions(-) diff --git a/typescript/packages/x402-express/src/index.ts b/typescript/packages/x402-express/src/index.ts index 3b996457f4..291e61e9e2 100644 --- a/typescript/packages/x402-express/src/index.ts +++ b/typescript/packages/x402-express/src/index.ts @@ -1,7 +1,7 @@ import { NextFunction, Request, Response } from "express"; import { Address, getAddress } from "viem"; import { Address as SolanaAddress } from "@solana/kit"; -import { exact } from "x402/schemes"; +import { exact, deferred } from "x402/schemes"; import { computeRoutePatterns, findMatchingPaymentRequirements, @@ -15,18 +15,20 @@ import { ERC20TokenAmount, moneySchema, PaymentPayload, - PaymentRequirements, PaywallConfig, Resource, RoutesConfig, settleResponseHeader, SupportedEVMNetworks, SupportedSVMNetworks, + PaymentRequirementsSchema, + PaymentRequirements, + DEFERRRED_SCHEME, } from "x402/types"; import { useFacilitator } from "x402/verify"; /** - * Creates a payment middleware factory for Express + * Creates an exact payment middleware factory for Express * * @param payTo - The address to receive payments * @param routes - Configuration for protected routes and their payment requirements @@ -345,6 +347,174 @@ export function paymentMiddleware( }; } +/** + * Creates a deferred payment middleware factory for Express + * + * @param payTo - The address to receive payments + * @param routes - Configuration for protected routes and their payment requirements + * @param facilitator - Optional configuration for the payment facilitator service + * @returns An Express middleware handler + * + * @example + * ```typescript + * // Simple configuration - All endpoints are protected by $0.01 of USDC on base-sepolia + * app.use(deferredPaymentMiddleware( + * '0x123...', // payTo address + * { + * price: '$0.01', // USDC amount in dollars + * network: 'base-sepolia' + * }, + * // Optional facilitator configuration. Defaults to x402.org/facilitator for testnet usage + * )); + * + * // Advanced configuration - Endpoint-specific payment requirements & custom facilitator + * app.use(deferredPaymentMiddleware('0x123...', // payTo: The address to receive payments* { + * { + * '/weather/*': { + * price: '$0.001', // USDC amount in dollars + * network: 'base', + * config: { + * description: 'Access to weather data' + * } + * } + * }, + * { + * url: 'https://facilitator.example.com', + * createAuthHeaders: async () => ({ + * verify: { "Authorization": "Bearer token" }, + * settle: { "Authorization": "Bearer token" } + * }) + * }, + * { + * cdpClientKey: 'your-cdp-client-key', + * appLogo: '/images/logo.svg', + * appName: 'My App', + * } + * )); + * ``` + */ +export function deferredPaymentMiddleware( + payTo: Address, + routes: RoutesConfig, + facilitator?: FacilitatorConfig, +) { + const { verify } = useFacilitator(facilitator); + const x402Version = 1; + + // Pre-compile route patterns to regex and extract verbs + const routePatterns = computeRoutePatterns(routes); + + return async function paymentMiddleware( + req: Request, + res: Response, + next: NextFunction, + ): Promise { + const matchingRoute = findMatchingRoute(routePatterns, req.path, req.method.toUpperCase()); + + if (!matchingRoute) { + return next(); + } + + const { price, network, config = {} } = matchingRoute.config; + const { description, mimeType, maxTimeoutSeconds, outputSchema, resource } = config; + + const atomicAmountForAsset = processPriceToAtomicAmount(price, network); + if ("error" in atomicAmountForAsset) { + throw new Error(atomicAmountForAsset.error); + } + const { maxAmountRequired, asset } = atomicAmountForAsset; + + const resourceUrl: Resource = + resource || (`${req.protocol}://${req.headers.host}${req.path}` as Resource); + + const payment = req.header("X-PAYMENT"); + const paymentBuyer = req.header("X-PAYMENT-BUYER"); + + const extra = await config.extraGetter?.(payment, paymentBuyer); + const unparsedPaymentRequirements = [ + { + scheme: DEFERRRED_SCHEME, + network, + maxAmountRequired, + resource: resourceUrl, + description: description ?? "", + mimeType: mimeType ?? "", + payTo: getAddress(payTo), + maxTimeoutSeconds: maxTimeoutSeconds ?? 60, + asset: getAddress(asset.address), + outputSchema: outputSchema ?? undefined, + extra, + }, + ]; + + const paymentRequirements = unparsedPaymentRequirements.map(req => { + const parsed = PaymentRequirementsSchema.safeParse(req); + if (!parsed.success) { + throw new Error(`Invalid payment requirements: ${parsed.error.message}`); + } + return parsed.data; + }); + + if (!payment) { + res.status(402).json({ + x402Version, + error: "X-PAYMENT header is required", + accepts: toJsonSafe(paymentRequirements), + }); + return; + } + + let decodedPayment: PaymentPayload; + try { + decodedPayment = deferred.evm.decodePayment(payment); + decodedPayment.x402Version = x402Version; + } catch (error) { + res.status(402).json({ + x402Version, + error: error || "Invalid or malformed payment header", + accepts: toJsonSafe(paymentRequirements), + }); + return; + } + + const selectedPaymentRequirements = findMatchingPaymentRequirements( + paymentRequirements, + decodedPayment, + ); + if (!selectedPaymentRequirements) { + res.status(402).json({ + x402Version, + error: "Unable to find matching payment requirements", + accepts: toJsonSafe(paymentRequirements), + }); + return; + } + + try { + const response = await verify(decodedPayment, selectedPaymentRequirements); + if (!response.isValid) { + res.status(402).json({ + x402Version, + error: response.invalidReason, + accepts: toJsonSafe(paymentRequirements), + payer: response.payer, + }); + return; + } + } catch (error) { + res.status(402).json({ + x402Version, + error, + accepts: toJsonSafe(paymentRequirements), + }); + return; + } + + // Proceed to the next middleware or route handler + next(); + }; +} + export type { Money, Network, From 35666a22509f930deed5c40c6dd8ff5108ad0edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 31 Jul 2025 10:47:40 -0300 Subject: [PATCH 034/116] fix: better middleware for deferred MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-express/src/index.ts | 110 +++++++++++++++++- 1 file changed, 106 insertions(+), 4 deletions(-) diff --git a/typescript/packages/x402-express/src/index.ts b/typescript/packages/x402-express/src/index.ts index 291e61e9e2..83f6751434 100644 --- a/typescript/packages/x402-express/src/index.ts +++ b/typescript/packages/x402-express/src/index.ts @@ -24,6 +24,10 @@ import { PaymentRequirementsSchema, PaymentRequirements, DEFERRRED_SCHEME, + DeferredEvmPayloadSchema, + EXACT_SCHEME, + DeferredEvmPayloadVoucher, + PaymentRequirementsExtra, } from "x402/types"; import { useFacilitator } from "x402/verify"; @@ -124,7 +128,7 @@ export function paymentMiddleware( // evm networks if (SupportedEVMNetworks.includes(network)) { paymentRequirements.push({ - scheme: "exact", + scheme: EXACT_SCHEME, network, maxAmountRequired, resource: resourceUrl, @@ -302,7 +306,7 @@ export function paymentMiddleware( }; // Proceed to the next middleware or route handler - await next(); + next(); // If the response from the protected route is >= 400, do not settle payment if (res.statusCode >= 400) { @@ -352,6 +356,8 @@ export function paymentMiddleware( * * @param payTo - The address to receive payments * @param routes - Configuration for protected routes and their payment requirements + * @param getLatestVoucher - A function to get the latest voucher for a given buyer and seller. Needs to be implemented by the server. + * @param escrow - The escrow address * @param facilitator - Optional configuration for the payment facilitator service * @returns An Express middleware handler * @@ -396,6 +402,11 @@ export function paymentMiddleware( export function deferredPaymentMiddleware( payTo: Address, routes: RoutesConfig, + getLatestVoucher: ( + buyer: string, + seller: string, + ) => Promise<(DeferredEvmPayloadVoucher & { signature: string }) | null>, + escrow: Address, facilitator?: FacilitatorConfig, ) { const { verify } = useFacilitator(facilitator); @@ -430,7 +441,6 @@ export function deferredPaymentMiddleware( const payment = req.header("X-PAYMENT"); const paymentBuyer = req.header("X-PAYMENT-BUYER"); - const extra = await config.extraGetter?.(payment, paymentBuyer); const unparsedPaymentRequirements = [ { scheme: DEFERRRED_SCHEME, @@ -443,7 +453,13 @@ export function deferredPaymentMiddleware( maxTimeoutSeconds: maxTimeoutSeconds ?? 60, asset: getAddress(asset.address), outputSchema: outputSchema ?? undefined, - extra, + extra: await getPaymentRequirementsExtra( + payment, + paymentBuyer, + payTo, + escrow, + getLatestVoucher, + ), }, ]; @@ -502,6 +518,7 @@ export function deferredPaymentMiddleware( return; } } catch (error) { + console.log(error); res.status(402).json({ x402Version, error, @@ -515,6 +532,91 @@ export function deferredPaymentMiddleware( }; } +/** + * Generate a new voucher id + * + * @returns A new voucher id + */ +function generateVoucherId() { + return `0x${Date.now().toString(16)}${Math.random().toString(16).slice(2)}`.padEnd(66, "0"); +} + +/** + * Get the extra data for the payment requirements + * + * @param paymentHeader - The x-payment header + * @param paymentBuyerHeader - The x-payment-buyer header + * @param seller - The seller address + * @param escrow - The escrow address + * @param getLatestVoucher - A function to get the latest voucher for a given buyer and seller. + * @returns The extra data for the payment requirements + */ +async function getPaymentRequirementsExtra( + paymentHeader: string | undefined, + paymentBuyerHeader: string | undefined, + seller: Address, + escrow: Address, + getLatestVoucher: ( + buyer: string, + seller: string, + ) => Promise<(DeferredEvmPayloadVoucher & { signature: string }) | null>, +): Promise { + const newVoucher = { + type: "new" as const, + voucher: { + id: generateVoucherId(), + escrow, + }, + }; + + // No header, new voucher + if (!paymentHeader) { + if (paymentBuyerHeader) { + const latestVoucher = await getLatestVoucher(paymentBuyerHeader, seller); + + // No voucher history, new voucher + if (!latestVoucher) { + return newVoucher; + } + + // If we made it here, means we need to aggregate the last voucher + return { + type: "aggregation" as const, + signature: latestVoucher.signature, + voucher: { + ...latestVoucher, + }, + }; + } + return newVoucher; + } + + // Wrong payload, new voucher + const paymentRequirements = DeferredEvmPayloadSchema.safeParse( + deferred.evm.decodePayment(paymentHeader).payload, + ); + if (!paymentRequirements.success) { + return newVoucher; + } + + // Get the latest voucher for the buyer + const latestVoucher = await getLatestVoucher(paymentRequirements.data.voucher.buyer, seller); + + // No voucher history, new voucher + if (!latestVoucher) { + return newVoucher; + } + + // If we made it here, means we need to aggregate the last voucher + return { + type: "aggregation" as const, + signature: latestVoucher.signature, + voucher: { + ...latestVoucher, + }, + }; +} + export type { Money, Network, From 5103c9edc0bf1f2544522aee90f58e40cdc89be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 31 Jul 2025 14:26:26 -0300 Subject: [PATCH 035/116] fix: add missing type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/types/verify/x402Specs.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index 1ca52351fc..a98e6620a6 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -47,6 +47,7 @@ export const PaymentRequirementsSchema = z.discriminatedUnion("scheme", [ DeferredPaymentRequirementsSchema, ]); export type PaymentRequirements = z.infer; +export type PaymentRequirementsExtra = z.infer["extra"]; // x402PaymentPayload export const PaymentPayloadSchema = z.discriminatedUnion("scheme", [ From e8afde46ac11066194ae136a6ba842dab25090e3 Mon Sep 17 00:00:00 2001 From: Chris Whited Date: Thu, 31 Jul 2025 20:57:32 +0100 Subject: [PATCH 036/116] feat(x402-axios): add X-BUYER-header to axios request interceptor (#11) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(x402-axios): add X-BUYER-header to axios request interceptor * feat(x402-axios): add X-PAYMENT-BUYER to 402 subsequent request * feat(x402-axios): do NOT send X-PAYMENT-BUYER on 402 subsequent request * fix: update pnpm-lock.yaml in examples/typescript The lockfile was out of sync with the x402-axios package.json which recently added vitest-mock-extended as a devDependency. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * feat(x402-axios): format fixes?? --------- Co-authored-by: Claude --- examples/typescript/pnpm-lock.yaml | 27 + .../typescript/servers/express/package.json | 2 +- typescript/packages/x402-axios/package.json | 1 + .../packages/x402-axios/src/index.test.ts | 145 +- typescript/packages/x402-axios/src/index.ts | 27 +- typescript/pnpm-lock.yaml | 4756 ++++++++--------- 6 files changed, 2480 insertions(+), 2478 deletions(-) diff --git a/examples/typescript/pnpm-lock.yaml b/examples/typescript/pnpm-lock.yaml index 0395e10fb4..f6ec500465 100644 --- a/examples/typescript/pnpm-lock.yaml +++ b/examples/typescript/pnpm-lock.yaml @@ -245,6 +245,9 @@ importers: vitest: specifier: ^3.0.5 version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + vitest-mock-extended: + specifier: ^3.1.0 + version: 3.1.0(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1)) ../../typescript/packages/x402-express: dependencies: @@ -9090,6 +9093,14 @@ packages: ts-case-convert@2.1.0: resolution: {integrity: sha512-Ye79el/pHYXfoew6kqhMwCoxp4NWjKNcm2kBzpmEMIU9dd9aBmHNNFtZ+WTm0rz1ngyDmfqDXDlyUnBXayiD0w==} + ts-essentials@10.1.1: + resolution: {integrity: sha512-4aTB7KLHKmUvkjNj8V+EdnmuVTiECzn3K+zIbRthumvHu+j44x3w63xpfs0JL3NGIzGXqoQ7AV591xHO+XrOTw==} + peerDependencies: + typescript: '>=4.5.0' + peerDependenciesMeta: + typescript: + optional: true + ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -9591,6 +9602,12 @@ packages: yaml: optional: true + vitest-mock-extended@3.1.0: + resolution: {integrity: sha512-vCM0VkuocOUBwwqwV7JB7YStw07pqeKvEIrZnR8l3PtwYi6rAAJAyJACeC1UYNfbQWi85nz7EdiXWBFI5hll2g==} + peerDependencies: + typescript: 3.x || 4.x || 5.x + vitest: '>=3.0.0' + vitest@3.2.4: resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -22200,6 +22217,10 @@ snapshots: ts-case-convert@2.1.0: {} + ts-essentials@10.1.1(typescript@5.9.2): + optionalDependencies: + typescript: 5.9.2 + ts-interface-checker@0.1.13: {} tsconfck@3.1.6(typescript@5.9.2): @@ -22723,6 +22744,12 @@ snapshots: tsx: 4.20.5 yaml: 2.8.1 + vitest-mock-extended@3.1.0(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1)): + dependencies: + ts-essentials: 10.1.1(typescript@5.9.2) + typescript: 5.9.2 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 diff --git a/examples/typescript/servers/express/package.json b/examples/typescript/servers/express/package.json index 10f7a9e41f..0feb65aee5 100644 --- a/examples/typescript/servers/express/package.json +++ b/examples/typescript/servers/express/package.json @@ -30,4 +30,4 @@ "tsx": "^4.7.0", "typescript": "^5.3.0" } -} \ No newline at end of file +} diff --git a/typescript/packages/x402-axios/package.json b/typescript/packages/x402-axios/package.json index 2d8c1e1a47..99769825b1 100644 --- a/typescript/packages/x402-axios/package.json +++ b/typescript/packages/x402-axios/package.json @@ -35,6 +35,7 @@ "typescript": "^5.7.3", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.0.5", + "vitest-mock-extended": "^3.1.0", "vite": "^6.2.6" }, "dependencies": { diff --git a/typescript/packages/x402-axios/src/index.test.ts b/typescript/packages/x402-axios/src/index.test.ts index 5dd449409a..0d799ac7c3 100644 --- a/typescript/packages/x402-axios/src/index.test.ts +++ b/typescript/packages/x402-axios/src/index.test.ts @@ -6,6 +6,7 @@ import { InternalAxiosRequestConfig, } from "axios"; import { beforeEach, describe, expect, it, vi } from "vitest"; +import { mock } from "vitest-mock-extended"; import { evm, PaymentRequirements, @@ -24,6 +25,40 @@ vi.mock("x402/client", () => ({ selectPaymentRequirements: vi.fn(), })); +const createErrorConfig = ( + isRetry = false, + headers = new AxiosHeaders(), +): InternalAxiosRequestConfig => + ({ + headers, + url: "https://api.example.com", + method: "GET", + ...(isRetry ? { __is402Retry: true } : {}), + }) as InternalAxiosRequestConfig; + +const createAxiosError = ( + status: number, + config?: InternalAxiosRequestConfig, + data?: { accepts: PaymentRequirements[]; x402Version: number }, + headers?: AxiosHeaders, +): AxiosError => { + return new AxiosError( + "Error", + "ERROR", + config, + { + headers: headers ?? {}, + }, + { + status, + statusText: status === 402 ? "Payment Required" : "Not Found", + data, + headers: headers ?? {}, + config: config || createErrorConfig(), + }, + ); +}; + describe("withPaymentInterceptor()", () => { let mockAxiosClient: AxiosInstance; let mockWalletClient: typeof evm.SignerWallet; @@ -43,34 +78,6 @@ describe("withPaymentInterceptor()", () => { }, ]; - const createErrorConfig = (isRetry = false): InternalAxiosRequestConfig => - ({ - headers: new AxiosHeaders(), - url: "https://api.example.com", - method: "GET", - ...(isRetry ? { __is402Retry: true } : {}), - }) as InternalAxiosRequestConfig; - - const createAxiosError = ( - status: number, - config?: InternalAxiosRequestConfig, - data?: { accepts: PaymentRequirements[]; x402Version: number }, - ): AxiosError => { - return new AxiosError( - "Error", - "ERROR", - config, - {}, - { - status, - statusText: status === 402 ? "Payment Required" : "Not Found", - data, - headers: {}, - config: config || createErrorConfig(), - }, - ); - }; - beforeEach(async () => { // Reset mocks before each test vi.resetAllMocks(); @@ -365,7 +372,10 @@ describe("withPaymentInterceptor() - SVM and MultiNetwork", () => { describe("withDeferredPaymentInterceptor", () => { let mockAxiosClient: AxiosInstance; let mockWalletClient: typeof evm.SignerWallet; - let interceptor: (error: AxiosError) => Promise; + let requestInterceptor: ( + request: InternalAxiosRequestConfig, + ) => Promise; + let responseInterceptor: (error: AxiosError) => Promise; const escrowAddress = "0xffffff12345678901234567890123456789fffff"; const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; @@ -390,34 +400,6 @@ describe("withDeferredPaymentInterceptor", () => { }, ]; - const createErrorConfig = (isRetry = false): InternalAxiosRequestConfig => - ({ - headers: new AxiosHeaders(), - url: "https://api.example.com", - method: "GET", - ...(isRetry ? { __is402Retry: true } : {}), - }) as InternalAxiosRequestConfig; - - const createAxiosError = ( - status: number, - config?: InternalAxiosRequestConfig, - data?: { accepts: PaymentRequirements[]; x402Version: number }, - ): AxiosError => { - return new AxiosError( - "Error", - "ERROR", - config, - {}, - { - status, - statusText: status === 402 ? "Payment Required" : "Not Found", - data, - headers: {}, - config: config || createErrorConfig(), - }, - ); - }; - beforeEach(async () => { // Reset mocks before each test vi.resetAllMocks(); @@ -428,6 +410,9 @@ describe("withDeferredPaymentInterceptor", () => { response: { use: vi.fn(), }, + request: { + use: vi.fn(), + }, }, request: vi.fn(), } as unknown as AxiosInstance; @@ -435,6 +420,7 @@ describe("withDeferredPaymentInterceptor", () => { // Mock wallet client mockWalletClient = { signMessage: vi.fn(), + address: "0x1234567890123456789012345678901234567890", } as unknown as typeof evm.SignerWallet; // Mock payment requirements selector @@ -445,8 +431,10 @@ describe("withDeferredPaymentInterceptor", () => { // Set up the interceptor withDeferredPaymentInterceptor(mockAxiosClient, mockWalletClient); - interceptor = (mockAxiosClient.interceptors.response.use as ReturnType).mock + requestInterceptor = (mockAxiosClient.interceptors.request.use as ReturnType).mock .calls[0][1]; + responseInterceptor = (mockAxiosClient.interceptors.response.use as ReturnType) + .mock.calls[0][1]; }); it("should return the axios client instance", () => { @@ -454,18 +442,33 @@ describe("withDeferredPaymentInterceptor", () => { expect(result).toBe(mockAxiosClient); }); - it("should set up response interceptor", () => { + it("should set up request and response interceptor", () => { + expect(mockAxiosClient.interceptors.request.use).toHaveBeenCalled(); expect(mockAxiosClient.interceptors.response.use).toHaveBeenCalled(); }); it("should not handle non-402 errors", async () => { const error = createAxiosError(404); - await expect(interceptor(error)).rejects.toBe(error); + await expect(responseInterceptor(error)).rejects.toBe(error); + }); + + it("should send the X-PAYMENT-BUYER with the request headers", async () => { + const request = mock({ + headers: new AxiosHeaders().set("X-PAYMENT-BUYER", mockWalletClient.address), + }); + const updatedRequest = await requestInterceptor(request); + expect(updatedRequest.headers.has("X-PAYMENT-BUYER")); + const xPaymentBuyer = updatedRequest.headers.get("X-PAYMENT-BUYER"); + expect(xPaymentBuyer).not.toBeNull(); + expect(xPaymentBuyer).toEqual(mockWalletClient.address); }); it("should handle 402 errors and retry with payment header", async () => { const paymentHeader = "payment-header-value"; - const successResponse = { data: "success" } as AxiosResponse; + const successResponse = { + data: "success", + headers: new AxiosHeaders().set("X-PAYMENT-BUYER", mockWalletClient.address), + } as AxiosResponse; const { createPaymentHeader, selectPaymentRequirements } = await import("x402/client"); (createPaymentHeader as ReturnType).mockResolvedValue(paymentHeader); @@ -474,12 +477,12 @@ describe("withDeferredPaymentInterceptor", () => { ); (mockAxiosClient.request as ReturnType).mockResolvedValue(successResponse); - const error = createAxiosError(402, createErrorConfig(), { + const error = createAxiosError(402, createErrorConfig(false), { accepts: validPaymentRequirements, x402Version: 1, }); - const result = await interceptor(error); + const result = await responseInterceptor(error); expect(result).toBe(successResponse); expect(selectPaymentRequirements).toHaveBeenCalledWith( @@ -492,14 +495,14 @@ describe("withDeferredPaymentInterceptor", () => { 1, validPaymentRequirements[0], ); - expect(mockAxiosClient.request).toHaveBeenCalledWith({ + + const actualCall = (mockAxiosClient.request as ReturnType).mock.calls[0][0]; + expect(actualCall).toMatchObject({ ...error.config, - headers: new AxiosHeaders({ - "X-PAYMENT": paymentHeader, - "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", - }), __is402Retry: true, }); + expect(actualCall.headers.get("X-PAYMENT")).toBe(paymentHeader); + expect(actualCall.headers.get("Access-Control-Expose-Headers")).toBe("X-PAYMENT-RESPONSE"); }); it("should not retry if already retried", async () => { @@ -507,7 +510,7 @@ describe("withDeferredPaymentInterceptor", () => { accepts: validPaymentRequirements, x402Version: 1, }); - await expect(interceptor(error)).rejects.toBe(error); + await expect(responseInterceptor(error)).rejects.toBe(error); }); it("should reject if missing request config", async () => { @@ -515,7 +518,7 @@ describe("withDeferredPaymentInterceptor", () => { accepts: validPaymentRequirements, x402Version: 1, }); - await expect(interceptor(error)).rejects.toThrow("Missing axios request configuration"); + await expect(responseInterceptor(error)).rejects.toThrow("Missing axios request configuration"); }); it("should reject if payment header creation fails", async () => { @@ -527,6 +530,6 @@ describe("withDeferredPaymentInterceptor", () => { accepts: validPaymentRequirements, x402Version: 1, }); - await expect(interceptor(error)).rejects.toBe(paymentError); + await expect(responseInterceptor(error)).rejects.toBe(paymentError); }); }); diff --git a/typescript/packages/x402-axios/src/index.ts b/typescript/packages/x402-axios/src/index.ts index eb046e8c0e..17fd3110e7 100644 --- a/typescript/packages/x402-axios/src/index.ts +++ b/typescript/packages/x402-axios/src/index.ts @@ -1,4 +1,10 @@ -import { AxiosInstance, AxiosError } from "axios"; +import { AxiosError, AxiosInstance } from "axios"; +import { Client, LocalAccount } from "viem"; +import { + createPaymentHeader, + PaymentRequirementsSelector, + selectPaymentRequirements, +} from "x402/client"; import { Signer, MultiNetworkSigner, @@ -134,6 +140,25 @@ export function withDeferredPaymentInterceptor( walletClient: Wallet, paymentRequirementsSelector: PaymentRequirementsSelector = selectPaymentRequirements, ) { + // intercept the request to send a `X-PAYMENT-BUYER` header with each request + axiosClient.interceptors.request.use( + async request => { + const buyer = + (walletClient as LocalAccount).address || (walletClient as Client).account?.address; + if (buyer) { + request.headers.set("X-PAYMENT-BUYER", buyer); + } + + return request; + }, + async (error: AxiosError) => error, + { + synchronous: true, + runWhen() { + return true; + }, + }, + ); axiosClient.interceptors.response.use( response => response, async (error: AxiosError) => { diff --git a/typescript/pnpm-lock.yaml b/typescript/pnpm-lock.yaml index 8cfeb3f98c..6df72a4832 100644 --- a/typescript/pnpm-lock.yaml +++ b/typescript/pnpm-lock.yaml @@ -10,74 +10,74 @@ importers: devDependencies: tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) turbo: specifier: ^2.5.0 - version: 2.5.6 + version: 2.5.4 typescript: specifier: ^5.8.3 - version: 5.9.2 + version: 5.8.3 packages/coinbase-x402: dependencies: '@coinbase/cdp-sdk': specifier: ^1.29.0 - version: 1.36.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.38.2(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) viem: specifier: ^2.21.26 - version: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) x402: specifier: workspace:^ version: link:../x402 zod: specifier: ^3.24.2 - version: 3.25.76 + version: 3.25.67 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.29.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.15.33 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.29.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.34.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint@9.34.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.0(eslint@9.29.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.3 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.0)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.33)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.3)(yaml@2.8.0) packages/x402: dependencies: @@ -86,457 +86,460 @@ importers: version: 1.2.6 '@solana-program/compute-budget': specifier: ^0.8.0 - version: 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + version: 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))) '@solana-program/token': specifier: ^0.5.1 - version: 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + version: 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))) '@solana-program/token-2022': specifier: ^0.4.2 - version: 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(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.9.2)) + version: 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)) '@solana/kit': specifier: ^2.1.1 - version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 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/transaction-confirmation': specifier: ^2.1.1 - version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 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)) viem: specifier: ^2.21.26 - version: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) wagmi: specifier: ^2.15.6 - version: 2.16.9(@tanstack/query-core@5.85.9)(@tanstack/react-query@5.85.9(react@19.1.1))(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + version: 2.15.6(@tanstack/query-core@5.81.2)(@tanstack/react-query@5.81.2(react@19.1.0))(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67))(zod@3.25.67) zod: specifier: ^3.24.2 - version: 3.25.76 + version: 3.25.67 devDependencies: '@coinbase/onchainkit': specifier: ^0.38.14 - version: 0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + version: 0.38.15(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(bufferutil@4.0.9)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(utf-8-validate@5.0.10)(zod@3.25.67) '@craftamap/esbuild-plugin-html': specifier: ^0.9.0 - version: 0.9.0(bufferutil@4.0.9)(esbuild@0.25.9)(utf-8-validate@5.0.10) + version: 0.9.0(bufferutil@4.0.9)(esbuild@0.25.5)(utf-8-validate@5.0.10) '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.29.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.15.33 '@types/react': specifier: ^19 - version: 19.1.12 + version: 19.1.8 '@types/react-dom': specifier: ^19 - version: 19.1.9(@types/react@19.1.12) + version: 19.1.6(@types/react@19.1.8) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@wagmi/connectors': specifier: ^5.8.1 - version: 5.9.9(@types/react@19.1.12)(@vercel/functions@2.2.13)(@wagmi/core@2.20.3(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + version: 5.8.5(@types/react@19.1.8)(@wagmi/core@2.17.3(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)))(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67))(zod@3.25.67) '@wagmi/core': specifier: ^2.17.1 - version: 2.20.3(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + version: 2.17.3(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)) buffer: specifier: ^6.0.3 version: 6.0.3 esbuild: specifier: ^0.25.4 - version: 0.25.9 + version: 0.25.5 eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.29.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.34.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint@9.34.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.0(eslint@9.29.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 react: specifier: ^19.0.0 - version: 19.1.1 + version: 19.1.0 react-dom: specifier: ^19.0.0 - version: 19.1.1(react@19.1.1) + version: 19.1.0(react@19.1.0) tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.3 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.0)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.33)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.3)(yaml@2.8.0) packages/x402-axios: dependencies: axios: specifier: ^1.7.9 - version: 1.11.0 + version: 1.10.0 viem: specifier: ^2.21.26 - version: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) x402: specifier: workspace:^ version: link:../x402 zod: specifier: ^3.24.2 - version: 3.25.76 + version: 3.25.67 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.29.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.15.33 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.29.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.34.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint@9.34.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.0(eslint@9.29.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.3 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.0)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.33)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.3)(yaml@2.8.0) + vitest-mock-extended: + specifier: ^3.1.0 + version: 3.1.0(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.33)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.3)(yaml@2.8.0)) packages/x402-express: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.36.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.22.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) '@solana/kit': specifier: ^2.1.1 - version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 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)) express: specifier: ^4.18.2 version: 4.21.2 viem: specifier: ^2.21.26 - version: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) x402: specifier: workspace:^ version: link:../x402 zod: specifier: ^3.24.2 - version: 3.25.76 + version: 3.25.67 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.29.0 '@types/express': specifier: ^5.0.1 version: 5.0.3 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.15.33 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.29.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.34.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint@9.34.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.0(eslint@9.29.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.3 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.0)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.33)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.3)(yaml@2.8.0) packages/x402-fetch: dependencies: viem: specifier: ^2.21.26 - version: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) x402: specifier: workspace:^ version: link:../x402 zod: specifier: ^3.24.2 - version: 3.25.76 + version: 3.25.67 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.29.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.15.33 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.29.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.34.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint@9.34.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.0(eslint@9.29.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.3 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.0)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.33)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.3)(yaml@2.8.0) packages/x402-hono: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.36.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.22.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) '@solana/kit': specifier: ^2.1.1 - version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) hono: specifier: ^4.7.1 - version: 4.9.6 + version: 4.8.2 viem: specifier: ^2.21.26 - version: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) x402: specifier: workspace:^ version: link:../x402 zod: specifier: ^3.24.2 - version: 3.25.76 + version: 3.25.67 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.29.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.15.33 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.29.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.34.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint@9.34.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.0(eslint@9.29.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.3 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.0)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.33)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.3)(yaml@2.8.0) packages/x402-next: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.36.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.22.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) '@solana/kit': specifier: ^2.1.1 - version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) next: specifier: ^15.0.0 - version: 15.5.2(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.3.4(@babel/core@7.27.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) viem: specifier: ^2.21.26 - version: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) x402: specifier: workspace:^ version: link:../x402 zod: specifier: ^3.24.2 - version: 3.25.76 + version: 3.25.67 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.29.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.15.33 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.29.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.34.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint@9.34.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.0(eslint@9.29.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.3 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.0)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.33)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.3)(yaml@2.8.0) site: dependencies: '@heroicons/react': specifier: ^2.2.0 - version: 2.2.0(react@19.1.1) + version: 2.2.0(react@19.1.0) '@vercel/functions': specifier: ^2.2.8 version: 2.2.13 next: specifier: ^15.2.4 - version: 15.5.2(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.3.4(@babel/core@7.27.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: specifier: ^19.0.0 - version: 19.1.1 + version: 19.1.0 react-dom: specifier: ^19.0.0 - version: 19.1.1(react@19.1.1) + version: 19.1.0(react@19.1.0) viem: specifier: ^2.21.26 - version: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) wagmi: specifier: ^2.15.6 - version: 2.16.9(@tanstack/query-core@5.85.9)(@tanstack/react-query@5.85.9(react@19.1.1))(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + version: 2.15.6(@tanstack/query-core@5.81.2)(@tanstack/react-query@5.81.2(react@19.1.0))(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67))(zod@3.25.67) x402: specifier: workspace:* version: link:../packages/x402 x402-legacy: specifier: npm:x402@0.1.2 - version: x402@0.1.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: x402@0.1.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) x402-next: specifier: workspace:* version: link:../packages/x402-next @@ -546,40 +549,40 @@ importers: version: 3.3.1 '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.29.0 '@svgr/webpack': specifier: ^8.1.0 - version: 8.1.0(typescript@5.9.2) + version: 8.1.0(typescript@5.8.3) '@types/node': specifier: ^20 - version: 20.19.12 + version: 20.19.1 '@types/react': specifier: ^19 - version: 19.1.12 + version: 19.1.8 '@types/react-dom': specifier: ^19 - version: 19.1.9(@types/react@19.1.12) + version: 19.1.6(@types/react@19.1.8) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.29.0(jiti@1.21.7) eslint-config-next: specifier: 15.1.7 - version: 15.1.7(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + version: 15.1.7(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.34.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint@9.34.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.0(eslint@9.29.0(jiti@1.21.7))(prettier@3.5.2) postcss: specifier: ^8 version: 8.5.6 @@ -591,7 +594,7 @@ importers: version: 3.4.17 typescript: specifier: ^5 - version: 5.9.2 + version: 5.8.3 packages: @@ -613,16 +616,16 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.0': - resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} + '@babel/compat-data@7.27.5': + resolution: {integrity: sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.3': - resolution: {integrity: sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==} + '@babel/core@7.27.4': + resolution: {integrity: sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.3': - resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} + '@babel/generator@7.27.5': + resolution: {integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==} engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.27.3': @@ -633,8 +636,8 @@ packages: resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.28.3': - resolution: {integrity: sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==} + '@babel/helper-create-class-features-plugin@7.27.1': + resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -645,15 +648,11 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.6.5': - resolution: {integrity: sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==} + '@babel/helper-define-polyfill-provider@0.6.4': + resolution: {integrity: sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - '@babel/helper-member-expression-to-functions@7.27.1': resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} engines: {node: '>=6.9.0'} @@ -662,8 +661,8 @@ packages: resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.28.3': - resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + '@babel/helper-module-transforms@7.27.3': + resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -704,16 +703,16 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.28.3': - resolution: {integrity: sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==} + '@babel/helper-wrap-function@7.27.1': + resolution: {integrity: sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.3': - resolution: {integrity: sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==} + '@babel/helpers@7.27.6': + resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.3': - resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} + '@babel/parser@7.27.5': + resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==} engines: {node: '>=6.0.0'} hasBin: true @@ -741,8 +740,8 @@ packages: peerDependencies: '@babel/core': ^7.13.0 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3': - resolution: {integrity: sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1': + resolution: {integrity: sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -789,8 +788,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.28.0': - resolution: {integrity: sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==} + '@babel/plugin-transform-async-generator-functions@7.27.1': + resolution: {integrity: sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -807,8 +806,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.28.0': - resolution: {integrity: sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==} + '@babel/plugin-transform-block-scoping@7.27.5': + resolution: {integrity: sha512-JF6uE2s67f0y2RZcm2kpAUEbD50vH62TyWVebxwHAlbSdM49VqPz8t4a1uIjp4NIOIZ4xzLfjY5emt/RCyC7TQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -819,14 +818,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.28.3': - resolution: {integrity: sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==} + '@babel/plugin-transform-class-static-block@7.27.1': + resolution: {integrity: sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.28.3': - resolution: {integrity: sha512-DoEWC5SuxuARF2KdKmGUq3ghfPMO6ZzR12Dnp5gubwbeWJo4dbNWXJPVlwvh4Zlq6Z7YVvL8VFxeSOJgjsx4Sg==} + '@babel/plugin-transform-classes@7.27.1': + resolution: {integrity: sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -837,8 +836,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.28.0': - resolution: {integrity: sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==} + '@babel/plugin-transform-destructuring@7.27.3': + resolution: {integrity: sha512-s4Jrok82JpiaIprtY2nHsYmrThKvvwgHwjgd7UMiYhZaN0asdXNLr0y+NjTfkA7SyQE5i2Fb7eawUOZmLvyqOA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -867,12 +866,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-explicit-resource-management@7.28.0': - resolution: {integrity: sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-exponentiation-operator@7.27.1': resolution: {integrity: sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==} engines: {node: '>=6.9.0'} @@ -969,8 +962,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.28.0': - resolution: {integrity: sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==} + '@babel/plugin-transform-object-rest-spread@7.27.3': + resolution: {integrity: sha512-7ZZtznF9g4l2JCImCo5LNKFHB5eXnN39lLtLY5Tg+VkR0jwOt7TBciMckuiQIOIW7L5tkQOCh3bVGYeXgMx52Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -993,8 +986,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-parameters@7.27.7': - resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + '@babel/plugin-transform-parameters@7.27.1': + resolution: {integrity: sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1023,8 +1016,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-display-name@7.28.0': - resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==} + '@babel/plugin-transform-react-display-name@7.27.1': + resolution: {integrity: sha512-p9+Vl3yuHPmkirRrg021XiP+EETmPMQTLr6Ayjj85RLNEbb3Eya/4VI0vAdzQG9SEAl2Lnt7fy5lZyMzjYoZQQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1047,8 +1040,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.28.3': - resolution: {integrity: sha512-K3/M/a4+ESb5LEldjQb+XSrpY0nF+ZBFlTCbSnKaYAMfD8v33O6PMs4uYnOk19HlcsI8WMu3McdFPTiQHF/1/A==} + '@babel/plugin-transform-regenerator@7.27.5': + resolution: {integrity: sha512-uhB8yHerfe3MWnuLAhEbeQ4afVoqv8BQsPqrTv7e/jZ9y00kJL6l9a/f4OWaKxotmjzewfEyXE1vgDJenkQ2/Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1095,8 +1088,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.28.0': - resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==} + '@babel/plugin-transform-typescript@7.27.1': + resolution: {integrity: sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1125,8 +1118,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.28.3': - resolution: {integrity: sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==} + '@babel/preset-env@7.27.2': + resolution: {integrity: sha512-Ma4zSuYSlGNRlCLO+EAzLnCmJK2vdstgv+n7aUP+/IKZrOfWHOJVdSJtuub8RzHTj3ahD37k5OKJWvzf16TQyQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1148,30 +1141,30 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.28.3': - resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==} + '@babel/runtime@7.27.6': + resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} engines: {node: '>=6.9.0'} '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.3': - resolution: {integrity: sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==} + '@babel/traverse@7.27.4': + resolution: {integrity: sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + '@babel/types@7.27.6': + resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==} engines: {node: '>=6.9.0'} - '@base-org/account@1.1.1': - resolution: {integrity: sha512-IfVJPrDPhHfqXRDb89472hXkpvJuQQR7FDI9isLPHEqSYt/45whIoBxSPgZ0ssTt379VhQo4+87PWI1DoLSfAQ==} + '@coinbase/cdp-sdk@1.22.0': + resolution: {integrity: sha512-B5zOdRC0kJw+CKO2jJ1hVVefiEzXEtVMSdm8iHyjg5qn0CMtbgwBLllPlTMYR3u+idZatYEQAIc6ExVrP6X0Rw==} - '@coinbase/cdp-sdk@1.36.1': - resolution: {integrity: sha512-eL8PfuPMXdEKQ6v/AwlDbTpiLhmnwZPAxzJ2m90qL8oEQuYenALX8JqNKg0LBQ/sPM6c2vx109YvFx49g5vSYQ==} + '@coinbase/cdp-sdk@1.38.2': + resolution: {integrity: sha512-S7+xKeZGGi+zc1PotTeQ5Pvn5a0e4ikT+iMm8pPfPjObNlDEUKLei4cmRHON1wXgql0oDXn30YKTo1LQWxXvDw==} - '@coinbase/onchainkit@0.38.19': - resolution: {integrity: sha512-4uiujoTO5/8/dpWVZoTlBC7z0Y1N5fgBYDR6pKN/r6a8pX83ObUuOSGhSzJ8Xbu8NpPU6TXX+VuzLiwiLg/irg==} + '@coinbase/onchainkit@0.38.15': + resolution: {integrity: sha512-RlZ2I7XlNyuVaWjF7/1WY6LzQTaRH2bTitb1wfwTEfxM8a1matfitpNZ2vAVLjRqDvHvgzegfyW6xxS+dUuCxA==} peerDependencies: react: ^18 || ^19 react-dom: ^18 || ^19 @@ -1179,8 +1172,8 @@ packages: '@coinbase/wallet-sdk@3.9.3': resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} - '@coinbase/wallet-sdk@4.3.6': - resolution: {integrity: sha512-4q8BNG1ViL4mSAAvPAtpwlOs1gpC+67eQtgIwNvT3xyeyFFd+guwkc8bcX5rTmQhXpqnhzC4f0obACbP9CqMSA==} + '@coinbase/wallet-sdk@4.3.3': + resolution: {integrity: sha512-h8gMLQNvP5TIJVXFOyQZaxbi1Mg5alFR4Z2/PEIngdyXZEoQGcVhzyQGuDa3t9zpllxvqfAaKfzDhsfCo+nhSQ==} '@craftamap/esbuild-plugin-html@0.9.0': resolution: {integrity: sha512-V5LFrcGXQWU1SSzYPwxEFjF8IjeXW0oTKh5c0xyhGuTNoEnjgJRNSX83HnZ5TTAutJfo/MAyWA4Z9/fIwbMhUQ==} @@ -1188,8 +1181,8 @@ packages: peerDependencies: esbuild: '>=0.15.10' - '@csstools/color-helpers@5.1.0': - resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + '@csstools/color-helpers@5.0.2': + resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} engines: {node: '>=18'} '@csstools/css-calc@2.1.4': @@ -1199,8 +1192,8 @@ packages: '@csstools/css-parser-algorithms': ^3.0.5 '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-color-parser@3.1.0': - resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + '@csstools/css-color-parser@3.0.10': + resolution: {integrity: sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==} engines: {node: '>=18'} peerDependencies: '@csstools/css-parser-algorithms': ^3.0.5 @@ -1216,183 +1209,177 @@ packages: resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} engines: {node: '>=18'} - '@ecies/ciphers@0.2.4': - resolution: {integrity: sha512-t+iX+Wf5nRKyNzk8dviW3Ikb/280+aEJAnw9YXvCp2tYGPSkMki+NRY+8aNLmVFv3eNtMdvViPNOPxS8SZNP+w==} + '@ecies/ciphers@0.2.3': + resolution: {integrity: sha512-tapn6XhOueMwht3E2UzY0ZZjYokdaw9XtL9kEyjhQ/Fb9vL9xTFbOaI+fV0AWvTpYu4BNloC6getKW6NtSg4mA==} engines: {bun: '>=1', deno: '>=2', node: '>=16'} peerDependencies: '@noble/ciphers': ^1.0.0 - '@emnapi/core@1.5.0': - resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} + '@emnapi/core@1.4.3': + resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} - '@emnapi/runtime@1.5.0': - resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} - '@emnapi/wasi-threads@1.1.0': - resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@emnapi/wasi-threads@1.0.2': + resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} '@es-joy/jsdoccomment@0.50.2': resolution: {integrity: sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==} engines: {node: '>=18'} - '@esbuild/aix-ppc64@0.25.9': - resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} + '@esbuild/aix-ppc64@0.25.5': + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.9': - resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} + '@esbuild/android-arm64@0.25.5': + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.9': - resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} + '@esbuild/android-arm@0.25.5': + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.9': - resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} + '@esbuild/android-x64@0.25.5': + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.9': - resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} + '@esbuild/darwin-arm64@0.25.5': + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.9': - resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} + '@esbuild/darwin-x64@0.25.5': + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.9': - resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} + '@esbuild/freebsd-arm64@0.25.5': + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.9': - resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} + '@esbuild/freebsd-x64@0.25.5': + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.9': - resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} + '@esbuild/linux-arm64@0.25.5': + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.9': - resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} + '@esbuild/linux-arm@0.25.5': + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.9': - resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} + '@esbuild/linux-ia32@0.25.5': + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.9': - resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} + '@esbuild/linux-loong64@0.25.5': + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.9': - resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} + '@esbuild/linux-mips64el@0.25.5': + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.9': - resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} + '@esbuild/linux-ppc64@0.25.5': + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.9': - resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} + '@esbuild/linux-riscv64@0.25.5': + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.9': - resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} + '@esbuild/linux-s390x@0.25.5': + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.9': - resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} + '@esbuild/linux-x64@0.25.5': + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.9': - resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} + '@esbuild/netbsd-arm64@0.25.5': + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.9': - resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} + '@esbuild/netbsd-x64@0.25.5': + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.9': - resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} + '@esbuild/openbsd-arm64@0.25.5': + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.9': - resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} + '@esbuild/openbsd-x64@0.25.5': + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.9': - resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.25.9': - resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} + '@esbuild/sunos-x64@0.25.5': + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.9': - resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} + '@esbuild/win32-arm64@0.25.5': + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.9': - resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} + '@esbuild/win32-ia32@0.25.5': + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.9': - resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} + '@esbuild/win32-x64@0.25.5': + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.8.0': - resolution: {integrity: sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==} + '@eslint-community/eslint-utils@4.7.0': + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -1401,32 +1388,36 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} + '@eslint/config-array@0.20.1': + resolution: {integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.2.3': + resolution: {integrity: sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.3.1': - resolution: {integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==} + '@eslint/core@0.14.0': + resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.15.2': - resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} + '@eslint/core@0.15.0': + resolution: {integrity: sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.34.0': - resolution: {integrity: sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==} + '@eslint/js@9.29.0': + resolution: {integrity: sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.3.5': - resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} + '@eslint/plugin-kit@0.3.2': + resolution: {integrity: sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ethereumjs/common@3.2.0': @@ -1445,33 +1436,24 @@ packages: resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} engines: {node: '>=14'} - '@farcaster/frame-sdk@0.1.9': - resolution: {integrity: sha512-r5cAKgHn4w8Q1jaCi84uKqItfNRd6h8Lk0YyQaz5kMoEIeJ4C0gXPpyqKPYP2TVDFuvaexg2KvzCO2CQdygWyQ==} - engines: {node: '>=22.11.0'} + '@farcaster/frame-core@0.1.8': + resolution: {integrity: sha512-Y0JATQXa/iaqH3pCp8Dby4iCQbwqw7JJaGtfzUazdr7R+zs3EDP8DYQCkqJu6iGjE9gqgecB+b+DOZpnqMTDNw==} - '@farcaster/miniapp-core@0.3.8': - resolution: {integrity: sha512-LaRG1L3lxHqo5pP/E2CX9hNqusR0C8hX3QTV2+hzmQJz6IGvmSpH6Q9ivlLyDfbdqokiMFo5Y3Z1EX1zBHMEQQ==} + '@farcaster/frame-sdk@0.0.60': + resolution: {integrity: sha512-MHQwdFT1VPe3kS0NvnORBPb/DQXr8qpdSDgIgfrdVCB8byQ5uFELlr3gQMuFYFyLFQVXgbMl75z8O6+hvorqow==} - '@farcaster/miniapp-sdk@0.1.9': - resolution: {integrity: sha512-hn0dlIy0JP2Hx6PgKcn9bjYwyPS/SQgYJ/a0qjzG8ZsDfUdjsMPf3yI/jicBipTml/UUoKcbqXM68fsrsbNMKA==} - - '@farcaster/miniapp-wagmi-connector@1.0.0': - resolution: {integrity: sha512-vMRZbekUUctnAUvBFhNoEsJlujRRdxop94fDy5LrKiRR9ax0wtp8gCvLYO+LpaP2PtGs0HFpRwlHNDJWvBR8bg==} + '@farcaster/frame-wagmi-connector@0.0.53': + resolution: {integrity: sha512-+fonXzzj3KxTeUHbtt7lZUC4v/MhC2Y2KpQw7WcVamiDwedm+jTMqBIdrMrWRej/HSWrBQ1rDIOlsWxnv9CDng==} peerDependencies: - '@farcaster/miniapp-sdk': ^0.1.0 + '@farcaster/frame-sdk': ^0.0.64 '@wagmi/core': ^2.14.1 viem: ^2.21.55 - '@farcaster/quick-auth@0.0.6': - resolution: {integrity: sha512-tiZndhpfDtEhaKlkmS5cVDuS+A/tafqZT3y9I44rC69m3beJok6e8dIH2JhxVy3EvOWTyTBnrmNn6GOOh+qK6A==} + '@farcaster/quick-auth@0.0.5': + resolution: {integrity: sha512-Z8hWz/7c33zlmII2AJHja/Wz0C03mm2o+CEBtBylmiun1wC4FMgx1Fal699VQvBUG1lpcJ662WxuRNxKogktDw==} peerDependencies: typescript: 5.8.3 - '@gemini-wallet/core@0.2.0': - resolution: {integrity: sha512-vv9aozWnKrrPWQ3vIFcWk7yta4hQW1Ie0fsNNPeXnjAxkbXr2hqMagEptLuMxpEP2W3mnRu05VDNKzcvAuuZDw==} - peerDependencies: - viem: '>=2.0.0' - '@graphql-typed-document-node/core@3.2.0': resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} peerDependencies: @@ -1482,8 +1464,8 @@ packages: peerDependencies: react: '>= 16 || ^19.0.0-rc' - '@hono/node-server@1.19.1': - resolution: {integrity: sha512-h44e5s+ByUriaRIbeS/C74O8v90m0A95luyYQGMF7KEn96KkYMXO7bZAwombzTpjQTU4e0TkU8U1WBIXlwuwtA==} + '@hono/node-server@1.14.4': + resolution: {integrity: sha512-DnxpshhYewr2q9ZN8ez/M5mmc3sucr8CT1sIgIy1bkeUXut9XWDkqHoFHRhWIQgkYnKpVRxunyhK7WzpJeJ6qQ==} engines: {node: '>=18.14.1'} peerDependencies: hono: ^4 @@ -1492,136 +1474,134 @@ packages: resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.7': - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + '@humanwhocodes/retry@0.4.3': resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@img/sharp-darwin-arm64@0.34.3': - resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} + '@img/sharp-darwin-arm64@0.34.2': + resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.34.3': - resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} + '@img/sharp-darwin-x64@0.34.2': + resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.0': - resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} + '@img/sharp-libvips-darwin-arm64@1.1.0': + resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.0': - resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} + '@img/sharp-libvips-darwin-x64@1.1.0': + resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.2.0': - resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} + '@img/sharp-libvips-linux-arm64@1.1.0': + resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm@1.2.0': - resolution: {integrity: sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==} + '@img/sharp-libvips-linux-arm@1.1.0': + resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-ppc64@1.2.0': - resolution: {integrity: sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==} + '@img/sharp-libvips-linux-ppc64@1.1.0': + resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} cpu: [ppc64] os: [linux] - '@img/sharp-libvips-linux-s390x@1.2.0': - resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} + '@img/sharp-libvips-linux-s390x@1.1.0': + resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-x64@1.2.0': - resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} + '@img/sharp-libvips-linux-x64@1.1.0': + resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': - resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.2.0': - resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} cpu: [x64] os: [linux] - '@img/sharp-linux-arm64@0.34.3': - resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} + '@img/sharp-linux-arm64@0.34.2': + resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm@0.34.3': - resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} + '@img/sharp-linux-arm@0.34.2': + resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - '@img/sharp-linux-ppc64@0.34.3': - resolution: {integrity: sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ppc64] - os: [linux] - - '@img/sharp-linux-s390x@0.34.3': - resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} + '@img/sharp-linux-s390x@0.34.2': + resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] - '@img/sharp-linux-x64@0.34.3': - resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} + '@img/sharp-linux-x64@0.34.2': + resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.3': - resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} + '@img/sharp-linuxmusl-arm64@0.34.2': + resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-x64@0.34.3': - resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} + '@img/sharp-linuxmusl-x64@0.34.2': + resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.34.3': - resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} + '@img/sharp-wasm32@0.34.2': + resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-win32-arm64@0.34.3': - resolution: {integrity: sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==} + '@img/sharp-win32-arm64@0.34.2': + resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [win32] - '@img/sharp-win32-ia32@0.34.3': - resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} + '@img/sharp-win32-ia32@0.34.2': + resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.34.3': - resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} + '@img/sharp-win32-x64@0.34.2': + resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] @@ -1630,24 +1610,29 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/trace-mapping@0.3.30': - resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@lit-labs/ssr-dom-shim@1.4.0': - resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} + '@lit-labs/ssr-dom-shim@1.3.0': + resolution: {integrity: sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==} - '@lit/reactive-element@2.1.1': - resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} + '@lit/reactive-element@2.1.0': + resolution: {integrity: sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==} '@metamask/eth-json-rpc-provider@1.0.1': resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==} @@ -1680,10 +1665,6 @@ packages: resolution: {integrity: sha512-1ugFO1UoirU2esS3juZanS/Fo8C8XYocCuBpfZI5N7ECtoG+zu0wF+uWZASik6CkO6w9n/Iebt4iI4pT0vptpg==} engines: {node: '>=16.0.0'} - '@metamask/rpc-errors@7.0.2': - resolution: {integrity: sha512-YYYHsVYd46XwY2QZzpGeU4PSdRhHdxnzkB8piWGvJW2xbikZ3R+epAYEL4q/K8bh9JPTucsUdwRFnACor1aOYw==} - engines: {node: ^18.20 || ^20.17 || >=22} - '@metamask/safe-event-emitter@2.0.0': resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} @@ -1710,10 +1691,6 @@ packages: resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==} engines: {node: '>=16.0.0'} - '@metamask/utils@11.7.0': - resolution: {integrity: sha512-IamqpZF8Lr4WeXJ84fD+Sy+v1Zo05SYuMPHHBrZWpzVbnHAmXQpL4ckn9s5dfA+zylp3WGypaBPb6SBZdOhuNQ==} - engines: {node: ^18.18 || ^20.14 || >=22} - '@metamask/utils@5.0.2': resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==} engines: {node: '>=14.0.0'} @@ -1726,59 +1703,59 @@ packages: resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} engines: {node: '>=16.0.0'} - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + '@napi-rs/wasm-runtime@0.2.11': + resolution: {integrity: sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==} - '@next/env@15.5.2': - resolution: {integrity: sha512-Qe06ew4zt12LeO6N7j8/nULSOe3fMXE4dM6xgpBQNvdzyK1sv5y4oAP3bq4LamrvGCZtmRYnW8URFCeX5nFgGg==} + '@next/env@15.3.4': + resolution: {integrity: sha512-ZkdYzBseS6UjYzz6ylVKPOK+//zLWvD6Ta+vpoye8cW11AjiQjGYVibF0xuvT4L0iJfAPfZLFidaEzAOywyOAQ==} '@next/eslint-plugin-next@15.1.7': resolution: {integrity: sha512-kRP7RjSxfTO13NE317ek3mSGzoZlI33nc/i5hs1KaWpK+egs85xg0DJ4p32QEiHnR0mVjuUfhRIun7awqfL7pQ==} - '@next/swc-darwin-arm64@15.5.2': - resolution: {integrity: sha512-8bGt577BXGSd4iqFygmzIfTYizHb0LGWqH+qgIF/2EDxS5JsSdERJKA8WgwDyNBZgTIIA4D8qUtoQHmxIIquoQ==} + '@next/swc-darwin-arm64@15.3.4': + resolution: {integrity: sha512-z0qIYTONmPRbwHWvpyrFXJd5F9YWLCsw3Sjrzj2ZvMYy9NPQMPZ1NjOJh4ojr4oQzcGYwgJKfidzehaNa1BpEg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@15.5.2': - resolution: {integrity: sha512-2DjnmR6JHK4X+dgTXt5/sOCu/7yPtqpYt8s8hLkHFK3MGkka2snTv3yRMdHvuRtJVkPwCGsvBSwmoQCHatauFQ==} + '@next/swc-darwin-x64@15.3.4': + resolution: {integrity: sha512-Z0FYJM8lritw5Wq+vpHYuCIzIlEMjewG2aRkc3Hi2rcbULknYL/xqfpBL23jQnCSrDUGAo/AEv0Z+s2bff9Zkw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@15.5.2': - resolution: {integrity: sha512-3j7SWDBS2Wov/L9q0mFJtEvQ5miIqfO4l7d2m9Mo06ddsgUK8gWfHGgbjdFlCp2Ek7MmMQZSxpGFqcC8zGh2AA==} + '@next/swc-linux-arm64-gnu@15.3.4': + resolution: {integrity: sha512-l8ZQOCCg7adwmsnFm8m5q9eIPAHdaB2F3cxhufYtVo84pymwKuWfpYTKcUiFcutJdp9xGHC+F1Uq3xnFU1B/7g==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.5.2': - resolution: {integrity: sha512-s6N8k8dF9YGc5T01UPQ08yxsK6fUow5gG1/axWc1HVVBYQBgOjca4oUZF7s4p+kwhkB1bDSGR8QznWrFZ/Rt5g==} + '@next/swc-linux-arm64-musl@15.3.4': + resolution: {integrity: sha512-wFyZ7X470YJQtpKot4xCY3gpdn8lE9nTlldG07/kJYexCUpX1piX+MBfZdvulo+t1yADFVEuzFfVHfklfEx8kw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@15.5.2': - resolution: {integrity: sha512-o1RV/KOODQh6dM6ZRJGZbc+MOAHww33Vbs5JC9Mp1gDk8cpEO+cYC/l7rweiEalkSm5/1WGa4zY7xrNwObN4+Q==} + '@next/swc-linux-x64-gnu@15.3.4': + resolution: {integrity: sha512-gEbH9rv9o7I12qPyvZNVTyP/PWKqOp8clvnoYZQiX800KkqsaJZuOXkWgMa7ANCCh/oEN2ZQheh3yH8/kWPSEg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.5.2': - resolution: {integrity: sha512-/VUnh7w8RElYZ0IV83nUcP/J4KJ6LLYliiBIri3p3aW2giF+PAVgZb6mk8jbQSB3WlTai8gEmCAr7kptFa1H6g==} + '@next/swc-linux-x64-musl@15.3.4': + resolution: {integrity: sha512-Cf8sr0ufuC/nu/yQ76AnarbSAXcwG/wj+1xFPNbyNo8ltA6kw5d5YqO8kQuwVIxk13SBdtgXrNyom3ZosHAy4A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@15.5.2': - resolution: {integrity: sha512-sMPyTvRcNKXseNQ/7qRfVRLa0VhR0esmQ29DD6pqvG71+JdVnESJaHPA8t7bc67KD5spP3+DOCNLhqlEI2ZgQg==} + '@next/swc-win32-arm64-msvc@15.3.4': + resolution: {integrity: sha512-ay5+qADDN3rwRbRpEhTOreOn1OyJIXS60tg9WMYTWCy3fB6rGoyjLVxc4dR9PYjEdR2iDYsaF5h03NA+XuYPQQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@15.5.2': - resolution: {integrity: sha512-W5VvyZHnxG/2ukhZF/9Ikdra5fdNftxI6ybeVKYvBPDtyx7x4jPPSNduUkfH5fo3zG0JQ0bPxgy41af2JX5D4Q==} + '@next/swc-win32-x64-msvc@15.3.4': + resolution: {integrity: sha512-4kDt31Bc9DGyYs41FTL1/kNpDeHyha2TC0j5sRRoKCyrhNcfZ/nRQkAUlF27mETwm8QyHqIjHJitfcza2Iykfg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -1802,12 +1779,8 @@ packages: resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} 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.7': - resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + '@noble/curves@1.9.2': + resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==} engines: {node: ^14.21.3 || >=16} '@noble/hashes@1.4.0': @@ -1850,8 +1823,8 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@pkgr/core@0.2.9': - resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} + '@pkgr/core@0.2.7': + resolution: {integrity: sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} '@reown/appkit-common@1.7.8': @@ -1883,116 +1856,111 @@ packages: '@reown/appkit@1.7.8': resolution: {integrity: sha512-51kTleozhA618T1UvMghkhKfaPcc9JlKwLJ5uV+riHyvSoWPKPRIa5A6M1Wano5puNyW0s3fwywhyqTHSilkaA==} - '@rollup/rollup-android-arm-eabi@4.50.0': - resolution: {integrity: sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ==} + '@rollup/rollup-android-arm-eabi@4.44.0': + resolution: {integrity: sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.50.0': - resolution: {integrity: sha512-2O73dR4Dc9bp+wSYhviP6sDziurB5/HCym7xILKifWdE9UsOe2FtNcM+I4xZjKrfLJnq5UR8k9riB87gauiQtw==} + '@rollup/rollup-android-arm64@4.44.0': + resolution: {integrity: sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.50.0': - resolution: {integrity: sha512-vwSXQN8T4sKf1RHr1F0s98Pf8UPz7pS6P3LG9NSmuw0TVh7EmaE+5Ny7hJOZ0M2yuTctEsHHRTMi2wuHkdS6Hg==} + '@rollup/rollup-darwin-arm64@4.44.0': + resolution: {integrity: sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.50.0': - resolution: {integrity: sha512-cQp/WG8HE7BCGyFVuzUg0FNmupxC+EPZEwWu2FCGGw5WDT1o2/YlENbm5e9SMvfDFR6FRhVCBePLqj0o8MN7Vw==} + '@rollup/rollup-darwin-x64@4.44.0': + resolution: {integrity: sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.50.0': - resolution: {integrity: sha512-UR1uTJFU/p801DvvBbtDD7z9mQL8J80xB0bR7DqW7UGQHRm/OaKzp4is7sQSdbt2pjjSS72eAtRh43hNduTnnQ==} + '@rollup/rollup-freebsd-arm64@4.44.0': + resolution: {integrity: sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.50.0': - resolution: {integrity: sha512-G/DKyS6PK0dD0+VEzH/6n/hWDNPDZSMBmqsElWnCRGrYOb2jC0VSupp7UAHHQ4+QILwkxSMaYIbQ72dktp8pKA==} + '@rollup/rollup-freebsd-x64@4.44.0': + resolution: {integrity: sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.50.0': - resolution: {integrity: sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==} + '@rollup/rollup-linux-arm-gnueabihf@4.44.0': + resolution: {integrity: sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.50.0': - resolution: {integrity: sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg==} + '@rollup/rollup-linux-arm-musleabihf@4.44.0': + resolution: {integrity: sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.50.0': - resolution: {integrity: sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==} + '@rollup/rollup-linux-arm64-gnu@4.44.0': + resolution: {integrity: sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.50.0': - resolution: {integrity: sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ==} + '@rollup/rollup-linux-arm64-musl@4.44.0': + resolution: {integrity: sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.50.0': - resolution: {integrity: sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==} + '@rollup/rollup-linux-loongarch64-gnu@4.44.0': + resolution: {integrity: sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.50.0': - resolution: {integrity: sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==} + '@rollup/rollup-linux-powerpc64le-gnu@4.44.0': + resolution: {integrity: sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.50.0': - resolution: {integrity: sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==} + '@rollup/rollup-linux-riscv64-gnu@4.44.0': + resolution: {integrity: sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.50.0': - resolution: {integrity: sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==} + '@rollup/rollup-linux-riscv64-musl@4.44.0': + resolution: {integrity: sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.50.0': - resolution: {integrity: sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==} + '@rollup/rollup-linux-s390x-gnu@4.44.0': + resolution: {integrity: sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.50.0': - resolution: {integrity: sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA==} + '@rollup/rollup-linux-x64-gnu@4.44.0': + resolution: {integrity: sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.50.0': - resolution: {integrity: sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw==} + '@rollup/rollup-linux-x64-musl@4.44.0': + resolution: {integrity: sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.50.0': - resolution: {integrity: sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.50.0': - resolution: {integrity: sha512-q7cIIdFvWQoaCbLDUyUc8YfR3Jh2xx3unO8Dn6/TTogKjfwrax9SyfmGGK6cQhKtjePI7jRfd7iRYcxYs93esg==} + '@rollup/rollup-win32-arm64-msvc@4.44.0': + resolution: {integrity: sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.50.0': - resolution: {integrity: sha512-XzNOVg/YnDOmFdDKcxxK410PrcbcqZkBmz+0FicpW5jtjKQxcW1BZJEQOF0NJa6JO7CZhett8GEtRN/wYLYJuw==} + '@rollup/rollup-win32-ia32-msvc@4.44.0': + resolution: {integrity: sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.50.0': - resolution: {integrity: sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg==} + '@rollup/rollup-win32-x64-msvc@4.44.0': + resolution: {integrity: sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ==} cpu: [x64] os: [win32] '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@rushstack/eslint-patch@1.12.0': - resolution: {integrity: sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==} + '@rushstack/eslint-patch@1.11.0': + resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} '@safe-global/safe-apps-provider@0.18.6': resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==} @@ -2078,6 +2046,12 @@ packages: peerDependencies: typescript: '>=5' + '@solana/codecs-core@2.1.1': + resolution: {integrity: sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/codecs-core@2.3.0': resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} engines: {node: '>=20.18.0'} @@ -2100,6 +2074,12 @@ packages: peerDependencies: typescript: '>=5' + '@solana/codecs-numbers@2.1.1': + resolution: {integrity: sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/codecs-numbers@2.3.0': resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} engines: {node: '>=20.18.0'} @@ -2136,6 +2116,13 @@ packages: peerDependencies: typescript: '>=5' + '@solana/errors@2.1.1': + resolution: {integrity: sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + '@solana/errors@2.3.0': resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} engines: {node: '>=20.18.0'} @@ -2293,8 +2280,8 @@ packages: peerDependencies: '@solana/web3.js': ^1.95.3 - '@solana/spl-token@0.4.14': - resolution: {integrity: sha512-u09zr96UBpX4U685MnvQsNzlvw9TiY005hk1vJmJr7gMJldoPG1eYU5/wNEyOA5lkMLiR/gOi9SFD4MefOYEsA==} + '@solana/spl-token@0.4.13': + resolution: {integrity: sha512-cite/pYWQZZVvLbg5lsodSovbetK/eA24gaR0eeUeMuBAMNrT8XFCwaygKy0N2WSg3gSyjjNpIeAGBAKZaY/1w==} engines: {node: '>=16'} peerDependencies: '@solana/web3.js': ^1.95.5 @@ -2329,8 +2316,8 @@ packages: peerDependencies: typescript: '>=5.3.3' - '@solana/web3.js@1.98.4': - resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} + '@solana/web3.js@1.98.2': + resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} '@svgr/babel-plugin-add-jsx-attribute@8.0.0': resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} @@ -2410,17 +2397,20 @@ packages: resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} engines: {node: '>=14'} + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} '@swc/helpers@0.5.17': resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - '@tanstack/query-core@5.85.9': - resolution: {integrity: sha512-5fxb9vwyftYE6KFLhhhDyLr8NO75+Wpu7pmTo+TkwKmMX2oxZDoLwcqGP8ItKSpUMwk3urWgQDZfyWr5Jm9LsQ==} + '@tanstack/query-core@5.81.2': + resolution: {integrity: sha512-QLYkPdrudoMATDFa3MiLEwRhNnAlzHWDf0LKaXUqJd0/+QxN8uTPi7bahRlxoAyH0UbLMBdeDbYzWALj7THOtw==} - '@tanstack/react-query@5.85.9': - resolution: {integrity: sha512-2T5zgSpcOZXGkH/UObIbIkGmUPQqZqn7esVQFXLOze622h4spgWf5jmvrqAo9dnI13/hyMcNsF1jsoDcb59nJQ==} + '@tanstack/react-query@5.81.2': + resolution: {integrity: sha512-pe8kFlTrL2zFLlcAj2kZk9UaYYHDk9/1hg9EBaoO3cxDhOZf1FRGJeziSXKrVZyxIfs7b3aoOj/bw7Lie0mDUg==} peerDependencies: react: ^18 || ^19 @@ -2428,8 +2418,8 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} - '@tybys/wasm-util@0.10.0': - resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==} + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} @@ -2449,8 +2439,8 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/express-serve-static-core@5.0.7': - resolution: {integrity: sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ==} + '@types/express-serve-static-core@5.0.6': + resolution: {integrity: sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==} '@types/express@5.0.3': resolution: {integrity: sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==} @@ -2464,9 +2454,6 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/lodash@4.17.20': - resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} - '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} @@ -2476,11 +2463,11 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@20.19.12': - resolution: {integrity: sha512-lSOjyS6vdO2G2g2CWrETTV3Jz2zlCXHpu1rcubLKpz9oj+z/1CceHlj+yq53W+9zgb98nSov/wjEKYDNauD+Hw==} + '@types/node@20.19.1': + resolution: {integrity: sha512-jJD50LtlD2dodAEO653i3YF04NWak6jN3ky+Ri3Em3mGR39/glWiboM/IePaRbgwSfqM1TpGXfAg8ohn/4dTgA==} - '@types/node@22.18.0': - resolution: {integrity: sha512-m5ObIqwsUp6BZzyiy4RdZpzWGub9bqLJMvZDD0QMXhxjqMHMENlj+SqF5QxoUwaQNFe+8kz8XM8ZQhqkQPTgMQ==} + '@types/node@22.15.33': + resolution: {integrity: sha512-wzoocdnnpSxZ+6CjW4ADCK1jVmd1S/J3ArNWfn8FDDQtRm8dkDg7TA+mvek2wNrfCgwuZxqEOiB9B1XCJ6+dbw==} '@types/qs@6.14.0': resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} @@ -2488,13 +2475,13 @@ packages: '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/react-dom@19.1.9': - resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} + '@types/react-dom@19.1.6': + resolution: {integrity: sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==} peerDependencies: '@types/react': ^19.0.0 - '@types/react@19.1.12': - resolution: {integrity: sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==} + '@types/react@19.1.8': + resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==} '@types/send@0.17.5': resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==} @@ -2514,157 +2501,157 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@typescript-eslint/eslint-plugin@8.42.0': - resolution: {integrity: sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==} + '@typescript-eslint/eslint-plugin@8.35.0': + resolution: {integrity: sha512-ijItUYaiWuce0N1SoSMrEd0b6b6lYkYt99pqCPfybd+HKVXtEvYhICfLdwp42MhiI5mp0oq7PKEL+g1cNiz/Eg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.42.0 + '@typescript-eslint/parser': ^8.35.0 eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.42.0': - resolution: {integrity: sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==} + '@typescript-eslint/parser@8.35.0': + resolution: {integrity: sha512-6sMvZePQrnZH2/cJkwRpkT7DxoAWh+g6+GFRK6bV3YQo7ogi3SX5rgF6099r5Q53Ma5qeT7LGmOmuIutF4t3lA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/project-service@8.42.0': - resolution: {integrity: sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==} + '@typescript-eslint/project-service@8.35.0': + resolution: {integrity: sha512-41xatqRwWZuhUMF/aZm2fcUsOFKNcG28xqRSS6ZVr9BVJtGExosLAm5A1OxTjRMagx8nJqva+P5zNIGt8RIgbQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/scope-manager@8.42.0': - resolution: {integrity: sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==} + '@typescript-eslint/scope-manager@8.35.0': + resolution: {integrity: sha512-+AgL5+mcoLxl1vGjwNfiWq5fLDZM1TmTPYs2UkyHfFhgERxBbqHlNjRzhThJqz+ktBqTChRYY6zwbMwy0591AA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.42.0': - resolution: {integrity: sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==} + '@typescript-eslint/tsconfig-utils@8.35.0': + resolution: {integrity: sha512-04k/7247kZzFraweuEirmvUj+W3bJLI9fX6fbo1Qm2YykuBvEhRTPl8tcxlYO8kZZW+HIXfkZNoasVb8EV4jpA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/type-utils@8.42.0': - resolution: {integrity: sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==} + '@typescript-eslint/type-utils@8.35.0': + resolution: {integrity: sha512-ceNNttjfmSEoM9PW87bWLDEIaLAyR+E6BoYJQ5PfaDau37UGca9Nyq3lBk8Bw2ad0AKvYabz6wxc7DMTO2jnNA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/types@8.42.0': - resolution: {integrity: sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==} + '@typescript-eslint/types@8.35.0': + resolution: {integrity: sha512-0mYH3emanku0vHw2aRLNGqe7EXh9WHEhi7kZzscrMDf6IIRUQ5Jk4wp1QrledE/36KtdZrVfKnE32eZCf/vaVQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.42.0': - resolution: {integrity: sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==} + '@typescript-eslint/typescript-estree@8.35.0': + resolution: {integrity: sha512-F+BhnaBemgu1Qf8oHrxyw14wq6vbL8xwWKKMwTMwYIRmFFY/1n/9T/jpbobZL8vp7QyEUcC6xGrnAO4ua8Kp7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.42.0': - resolution: {integrity: sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==} + '@typescript-eslint/utils@8.35.0': + resolution: {integrity: sha512-nqoMu7WWM7ki5tPgLVsmPM8CkqtoPUG6xXGeefM5t4x3XumOEKMoUZPdi+7F+/EotukN4R9OWdmDxN80fqoZeg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/visitor-keys@8.42.0': - resolution: {integrity: sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==} + '@typescript-eslint/visitor-keys@8.35.0': + resolution: {integrity: sha512-zTh2+1Y8ZpmeQaQVIc/ZZxsx8UzgKJyNg1PTvjzC7WMhPSVS8bfDX34k1SrwOf016qd5RU3az2UxUNue3IfQ5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + '@unrs/resolver-binding-android-arm-eabi@1.9.2': + resolution: {integrity: sha512-tS+lqTU3N0kkthU+rYp0spAYq15DU8ld9kXkaKg9sbQqJNF+WPMuNHZQGCgdxrUOEO0j22RKMwRVhF1HTl+X8A==} cpu: [arm] os: [android] - '@unrs/resolver-binding-android-arm64@1.11.1': - resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + '@unrs/resolver-binding-android-arm64@1.9.2': + resolution: {integrity: sha512-MffGiZULa/KmkNjHeuuflLVqfhqLv1vZLm8lWIyeADvlElJ/GLSOkoUX+5jf4/EGtfwrNFcEaB8BRas03KT0/Q==} cpu: [arm64] os: [android] - '@unrs/resolver-binding-darwin-arm64@1.11.1': - resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + '@unrs/resolver-binding-darwin-arm64@1.9.2': + resolution: {integrity: sha512-dzJYK5rohS1sYl1DHdJ3mwfwClJj5BClQnQSyAgEfggbUwA9RlROQSSbKBLqrGfsiC/VyrDPtbO8hh56fnkbsQ==} cpu: [arm64] os: [darwin] - '@unrs/resolver-binding-darwin-x64@1.11.1': - resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + '@unrs/resolver-binding-darwin-x64@1.9.2': + resolution: {integrity: sha512-gaIMWK+CWtXcg9gUyznkdV54LzQ90S3X3dn8zlh+QR5Xy7Y+Efqw4Rs4im61K1juy4YNb67vmJsCDAGOnIeffQ==} cpu: [x64] os: [darwin] - '@unrs/resolver-binding-freebsd-x64@1.11.1': - resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + '@unrs/resolver-binding-freebsd-x64@1.9.2': + resolution: {integrity: sha512-S7QpkMbVoVJb0xwHFwujnwCAEDe/596xqY603rpi/ioTn9VDgBHnCCxh+UFrr5yxuMH+dliHfjwCZJXOPJGPnw==} cpu: [x64] os: [freebsd] - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + '@unrs/resolver-binding-linux-arm-gnueabihf@1.9.2': + resolution: {integrity: sha512-+XPUMCuCCI80I46nCDFbGum0ZODP5NWGiwS3Pj8fOgsG5/ctz+/zzuBlq/WmGa+EjWZdue6CF0aWWNv84sE1uw==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + '@unrs/resolver-binding-linux-arm-musleabihf@1.9.2': + resolution: {integrity: sha512-sqvUyAd1JUpwbz33Ce2tuTLJKM+ucSsYpPGl2vuFwZnEIg0CmdxiZ01MHQ3j6ExuRqEDUCy8yvkDKvjYFPb8Zg==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + '@unrs/resolver-binding-linux-arm64-gnu@1.9.2': + resolution: {integrity: sha512-UYA0MA8ajkEDCFRQdng/FVx3F6szBvk3EPnkTTQuuO9lV1kPGuTB+V9TmbDxy5ikaEgyWKxa4CI3ySjklZ9lFA==} cpu: [arm64] os: [linux] - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + '@unrs/resolver-binding-linux-arm64-musl@1.9.2': + resolution: {integrity: sha512-P/CO3ODU9YJIHFqAkHbquKtFst0COxdphc8TKGL5yCX75GOiVpGqd1d15ahpqu8xXVsqP4MGFP2C3LRZnnL5MA==} cpu: [arm64] os: [linux] - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + '@unrs/resolver-binding-linux-ppc64-gnu@1.9.2': + resolution: {integrity: sha512-uKStFlOELBxBum2s1hODPtgJhY4NxYJE9pAeyBgNEzHgTqTiVBPjfTlPFJkfxyTjQEuxZbbJlJnMCrRgD7ubzw==} cpu: [ppc64] os: [linux] - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + '@unrs/resolver-binding-linux-riscv64-gnu@1.9.2': + resolution: {integrity: sha512-LkbNnZlhINfY9gK30AHs26IIVEZ9PEl9qOScYdmY2o81imJYI4IMnJiW0vJVtXaDHvBvxeAgEy5CflwJFIl3tQ==} cpu: [riscv64] os: [linux] - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + '@unrs/resolver-binding-linux-riscv64-musl@1.9.2': + resolution: {integrity: sha512-vI+e6FzLyZHSLFNomPi+nT+qUWN4YSj8pFtQZSFTtmgFoxqB6NyjxSjAxEC1m93qn6hUXhIsh8WMp+fGgxCoRg==} cpu: [riscv64] os: [linux] - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + '@unrs/resolver-binding-linux-s390x-gnu@1.9.2': + resolution: {integrity: sha512-sSO4AlAYhSM2RAzBsRpahcJB1msc6uYLAtP6pesPbZtptF8OU/CbCPhSRW6cnYOGuVmEmWVW5xVboAqCnWTeHQ==} cpu: [s390x] os: [linux] - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + '@unrs/resolver-binding-linux-x64-gnu@1.9.2': + resolution: {integrity: sha512-jkSkwch0uPFva20Mdu8orbQjv2A3G88NExTN2oPTI1AJ+7mZfYW3cDCTyoH6OnctBKbBVeJCEqh0U02lTkqD5w==} cpu: [x64] os: [linux] - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + '@unrs/resolver-binding-linux-x64-musl@1.9.2': + resolution: {integrity: sha512-Uk64NoiTpQbkpl+bXsbeyOPRpUoMdcUqa+hDC1KhMW7aN1lfW8PBlBH4mJ3n3Y47dYE8qi0XTxy1mBACruYBaw==} cpu: [x64] os: [linux] - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + '@unrs/resolver-binding-wasm32-wasi@1.9.2': + resolution: {integrity: sha512-EpBGwkcjDicjR/ybC0g8wO5adPNdVuMrNalVgYcWi+gYtC1XYNuxe3rufcO7dA76OHGeVabcO6cSkPJKVcbCXQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + '@unrs/resolver-binding-win32-arm64-msvc@1.9.2': + resolution: {integrity: sha512-EdFbGn7o1SxGmN6aZw9wAkehZJetFPao0VGZ9OMBwKx6TkvDuj6cNeLimF/Psi6ts9lMOe+Dt6z19fZQ9Ye2fw==} cpu: [arm64] os: [win32] - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + '@unrs/resolver-binding-win32-ia32-msvc@1.9.2': + resolution: {integrity: sha512-JY9hi1p7AG+5c/dMU8o2kWemM8I6VZxfGwn1GCtf3c5i+IKcMo2NQ8OjZ4Z3/itvY/Si3K10jOBQn7qsD/whUA==} cpu: [ia32] os: [win32] - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + '@unrs/resolver-binding-win32-x64-msvc@1.9.2': + resolution: {integrity: sha512-ryoo+EB19lMxAd80ln9BVf8pdOAxLb97amrQ3SFN9OCRn/5M5wvwDgAe4i8ZjhpbiHoDeP8yavcTEnpKBo7lZg==} cpu: [x64] os: [win32] @@ -2710,18 +2697,18 @@ packages: '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@wagmi/connectors@5.9.9': - resolution: {integrity: sha512-6+eqU7P2OtxU2PkIw6kHojfYYUJykYG2K5rSkzVh29RDCAjhJqGEZW5f1b8kV5rUBORip1NpST8QTBNi96JHGQ==} + '@wagmi/connectors@5.8.5': + resolution: {integrity: sha512-CHh4uYP6MziCMlSVXmuAv7wMoYWdxXliuzwCRAxHNNkgXE7z37ez5XzJu0Sm39NUau3Fl8WSjwKo4a4w9BOYNA==} peerDependencies: - '@wagmi/core': 2.20.3 + '@wagmi/core': 2.17.3 typescript: '>=5.0.4' viem: 2.x peerDependenciesMeta: typescript: optional: true - '@wagmi/core@2.20.3': - resolution: {integrity: sha512-gsbuHnWxf0AYZISvR8LvF/vUCIq6/ZwT5f5/FKd6wLA7Wq05NihCvmQpIgrcVbpSJPL67wb6S8fXm3eJGJA1vQ==} + '@wagmi/core@2.17.3': + resolution: {integrity: sha512-fgZR9fAiCFtGaosTspkTx5lidccq9Z5xRWOk1HG0VfB6euQGw2//Db7upiP4uQ7DPst2YS9yQN2A1m9+iJLYCw==} peerDependencies: '@tanstack/query-core': '>=5.0.0' typescript: '>=5.0.4' @@ -2842,17 +2829,6 @@ packages: zod: optional: true - abitype@1.1.0: - resolution: {integrity: sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==} - peerDependencies: - typescript: '>=5.0.4' - zod: ^3.22.0 || ^4.0.0 - peerDependenciesMeta: - typescript: - optional: true - zod: - optional: true - accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -2867,8 +2843,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} agentkeepalive@4.6.0: @@ -2882,8 +2858,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.0: - resolution: {integrity: sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} ansi-styles@4.3.0: @@ -2984,25 +2960,28 @@ packages: peerDependencies: axios: 0.x || 1.x - axios@1.11.0: - resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==} + axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + + axios@1.12.2: + resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - babel-plugin-polyfill-corejs2@0.4.14: - resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} + babel-plugin-polyfill-corejs2@0.4.13: + resolution: {integrity: sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs3@0.13.0: - resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + babel-plugin-polyfill-corejs3@0.11.1: + resolution: {integrity: sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.5: - resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==} + babel-plugin-polyfill-regenerator@0.6.4: + resolution: {integrity: sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -3025,8 +3004,8 @@ packages: 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==} + bignumber.js@9.3.0: + resolution: {integrity: sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==} binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} @@ -3048,8 +3027,8 @@ packages: borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} - bowser@2.12.1: - resolution: {integrity: sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==} + bowser@2.11.0: + resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -3061,8 +3040,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.25.4: - resolution: {integrity: sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==} + browserslist@4.25.0: + resolution: {integrity: sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -3085,6 +3064,10 @@ packages: peerDependencies: esbuild: '>=0.18' + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -3121,19 +3104,19 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001739: - resolution: {integrity: sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==} + caniuse-lite@1.0.30001724: + resolution: {integrity: sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA==} - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} - engines: {node: '>=18'} + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.6.0: - resolution: {integrity: sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==} + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} charenc@0.0.2: @@ -3190,8 +3173,12 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} - commander@14.0.0: - resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + + commander@14.0.1: + resolution: {integrity: sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==} engines: {node: '>=20'} commander@2.20.3: @@ -3240,8 +3227,8 @@ packages: resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} - core-js-compat@3.45.1: - resolution: {integrity: sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==} + core-js-compat@3.43.0: + resolution: {integrity: sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -3276,8 +3263,8 @@ packages: crypt@0.0.2: resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} - css-select@5.2.2: - resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} css-tree@2.2.1: resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} @@ -3287,8 +3274,8 @@ packages: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} cssesc@3.0.0: @@ -3300,8 +3287,8 @@ packages: resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - cssstyle@4.6.0: - resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} + cssstyle@4.5.0: + resolution: {integrity: sha512-/7gw8TGrvH/0g564EnhgFZogTMVe+lifpB7LWU+PEsiq5o83TUXR3fDbzTRXOJhoJwck5IS9ez3Em5LNMMO2aw==} engines: {node: '>=18'} csstype@3.1.3: @@ -3371,8 +3358,8 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} - decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decimal.js@10.5.0: + resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} decode-uri-component@0.2.2: resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} @@ -3477,8 +3464,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.214: - resolution: {integrity: sha512-TpvUNdha+X3ybfU78NoQatKvQEm1oq3lf2QbnmCEdw+Bd9RuIAY+hJTvq1avzHM0f7EJfnH3vbCnbzKzisc/9Q==} + electron-to-chromium@1.5.173: + resolution: {integrity: sha512-2bFhXP2zqSfQHugjqJIDFVwa+qIxyNApenmXTp9EjaKtdPrES5Qcn9/aSFy/NaP2E+fWG/zxKu/LBvY36p5VNQ==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -3562,8 +3549,8 @@ packages: es6-promisify@5.0.0: resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} - esbuild@0.25.9: - resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} + esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} engines: {node: '>=18'} hasBin: true @@ -3646,8 +3633,8 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-prettier@5.5.4: - resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} + eslint-plugin-prettier@5.5.0: + resolution: {integrity: sha512-8qsOYwkkGrahrgoUv76NZi23koqXOGiiEzXMrT8Q7VcYaUISR+5MorIUxfWqYXN0fN/31WbSrxCxFkVQ43wwrA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -3684,8 +3671,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.34.0: - resolution: {integrity: sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==} + eslint@9.29.0: + resolution: {integrity: sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -3748,8 +3735,8 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - expect-type@1.2.2: - resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} + expect-type@1.2.1: + resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} engines: {node: '>=12.0.0'} express@4.21.2: @@ -3800,9 +3787,8 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} + fdir@6.4.6: + resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -3846,8 +3832,8 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -3863,6 +3849,10 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + form-data@4.0.3: + resolution: {integrity: sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==} + engines: {node: '>= 6'} + form-data@4.0.4: resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} engines: {node: '>= 6'} @@ -3925,6 +3915,10 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -3952,8 +3946,8 @@ packages: resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - h3@1.15.4: - resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} + h3@1.15.3: + resolution: {integrity: sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ==} has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} @@ -3982,8 +3976,8 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - hono@4.9.6: - resolution: {integrity: sha512-doVjXhSFvYZ7y0dNokjwwSahcrAfdz+/BCLvAMa/vHLzjj8+CFyV5xteThGUsKdkaasgN+gF2mUxao+SGLpUeA==} + hono@4.8.2: + resolution: {integrity: sha512-hM+1RIn9PK1I6SiTNS6/y7O1mvg88awYLFEuEtoiMtRyT3SD2iu9pSFgbBXT3b1Ua4IwzvSTLvwO0SEhDxCi4w==} engines: {node: '>=16.9.0'} html-encoding-sniffer@4.0.0: @@ -4013,9 +4007,6 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} - idb-keyval@6.2.1: - resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} - idb-keyval@6.2.2: resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} @@ -4230,8 +4221,8 @@ packages: jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} - jose@6.1.0: - resolution: {integrity: sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==} + jose@6.0.11: + resolution: {integrity: sha512-QxG7EaliDARm1O1S8BGakqncGT9s25bKL1WSf6/oa17Tkqwi8D2ZNglqCF+DsYF88/rV66Q/Q2mFAy697E1DUg==} joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} @@ -4333,11 +4324,11 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lit-element@4.2.1: - resolution: {integrity: sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==} + lit-element@4.2.0: + resolution: {integrity: sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==} - lit-html@3.3.1: - resolution: {integrity: sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==} + lit-html@3.3.0: + resolution: {integrity: sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==} lit@3.3.0: resolution: {integrity: sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==} @@ -4370,8 +4361,8 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + loupe@3.1.4: + resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -4382,8 +4373,8 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - magic-string@0.30.18: - resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} @@ -4455,8 +4446,8 @@ packages: typescript: optional: true - mlly@1.8.0: - resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + mlly@1.7.4: + resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -4475,8 +4466,8 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - napi-postinstall@0.3.3: - resolution: {integrity: sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==} + napi-postinstall@0.2.4: + resolution: {integrity: sha512-ZEzHJwBhZ8qQSbknHqYcdtQVr8zUgGyM/q6h6qAyhtyVMNrSgDhrC4disf03dYW0e+czXyLnZINnCTEkWy0eJg==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} hasBin: true @@ -4487,13 +4478,13 @@ packages: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} - next@15.5.2: - resolution: {integrity: sha512-H8Otr7abj1glFhbGnvUt3gz++0AF1+QoCXEBmd/6aKbfdFwrn0LpA836Ed5+00va/7HQSDD+mOoVhn3tNy3e/Q==} + next@15.3.4: + resolution: {integrity: sha512-mHKd50C+mCjam/gcnwqL1T1vPx/XQNFlXqFIVdgQdVAFY9iIQtY0IfaVflEYzKiqjeA7B0cYYMaCrmAYFjs4rA==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.51.1 + '@playwright/test': ^1.41.2 babel-plugin-react-compiler: '*' react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 @@ -4514,8 +4505,8 @@ packages: node-addon-api@2.0.2: resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} - node-fetch-native@1.6.7: - resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-fetch-native@1.6.6: + resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} @@ -4530,8 +4521,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-mock-http@1.0.2: - resolution: {integrity: sha512-zWaamgDUdo9SSLw47we78+zYw/bDr5gH8pH7oRRs8V3KmBtu8GLgGIbV2p/gRPd3LWpEOpjQj7X1FOU3VFMJ8g==} + node-mock-http@1.0.0: + resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==} node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} @@ -4543,8 +4534,8 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nwsapi@2.2.21: - resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} + nwsapi@2.2.20: + resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} obj-multiplex@1.0.0: resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} @@ -4622,16 +4613,8 @@ packages: 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.9.3: - resolution: {integrity: sha512-KzyJP+fPV4uhuuqrTZyok4DC7vFzi7HLUFiUNEmpbyh59htKWkOC98IONC1zgXJPbHAhQgqs6B0Z6StCGhmQvg==} + ox@0.8.1: + resolution: {integrity: sha512-e+z5epnzV+Zuz91YYujecW8cF01mzmrUtWotJ0oEPym/G82uccs7q0WDHTYL3eiONbTUEvcZrptAKLgTBD3u2A==} peerDependencies: typescript: '>=5.4.0' peerDependenciesMeta: @@ -4707,8 +4690,8 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} picocolors@1.1.1: @@ -4718,8 +4701,8 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} pify@2.3.0: @@ -4826,11 +4809,8 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} - preact@10.24.2: - resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} - - preact@10.27.1: - resolution: {integrity: sha512-V79raXEWch/rbqoNc7nT9E4ep7lu+mI3+sBmfRD4i1M73R3WLYcCtdI0ibxGVf4eQL8ZIz2nFacqEC+rmnOORQ==} + preact@10.26.9: + resolution: {integrity: sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA==} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -4906,16 +4886,16 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - react-dom@19.1.1: - resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==} + react-dom@19.1.0: + resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} peerDependencies: - react: ^19.1.1 + react: ^19.1.0 react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react@19.1.1: - resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} + react@19.1.0: + resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} engines: {node: '>=0.10.0'} read-cache@1.0.0: @@ -4997,13 +4977,13 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.50.0: - resolution: {integrity: sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw==} + rollup@4.44.0: + resolution: {integrity: sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rpc-websockets@9.1.3: - resolution: {integrity: sha512-I+kNjW0udB4Fetr3vvtRuYZJS0PcSPyyvBcH5sDdoV8DFs5E4W2pTr7aiMlKfPxANTClP9RlqCPolj9dd5MsEA==} + rpc-websockets@9.1.1: + resolution: {integrity: sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA==} rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} @@ -5078,13 +5058,12 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sha.js@2.4.12: - resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} - engines: {node: '>= 0.10'} + sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} hasBin: true - sharp@0.34.3: - resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} + sharp@0.34.2: + resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@2.0.0: @@ -5142,7 +5121,6 @@ packages: source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} - deprecated: The work that was done in this beta branch won't be included in future versions spdx-exceptions@2.5.0: resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} @@ -5150,8 +5128,8 @@ packages: spdx-expression-parse@4.0.0: resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} - spdx-license-ids@3.0.22: - resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + spdx-license-ids@3.0.21: + resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} split-on-first@1.1.0: resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} @@ -5187,6 +5165,10 @@ packages: stream-shift@1.0.3: resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + strict-uri-encode@2.0.0: resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} engines: {node: '>=4'} @@ -5292,8 +5274,8 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - synckit@0.11.11: - resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} + synckit@0.11.8: + resolution: {integrity: sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==} engines: {node: ^14.18.0 || >=16.0.0} tailwind-merge@2.6.0: @@ -5346,10 +5328,6 @@ packages: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - to-buffer@1.2.1: - resolution: {integrity: sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==} - engines: {node: '>= 0.4'} - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -5382,6 +5360,14 @@ packages: peerDependencies: typescript: '>=4.8.4' + ts-essentials@10.1.1: + resolution: {integrity: sha512-4aTB7KLHKmUvkjNj8V+EdnmuVTiECzn3K+zIbRthumvHu+j44x3w63xpfs0JL3NGIzGXqoQ7AV591xHO+XrOTw==} + peerDependencies: + typescript: '>=4.5.0' + peerDependenciesMeta: + typescript: + optional: true + ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -5423,43 +5409,43 @@ packages: typescript: optional: true - tsx@4.20.5: - resolution: {integrity: sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==} + tsx@4.20.3: + resolution: {integrity: sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==} engines: {node: '>=18.0.0'} hasBin: true - turbo-darwin-64@2.5.6: - resolution: {integrity: sha512-3C1xEdo4aFwMJAPvtlPqz1Sw/+cddWIOmsalHFMrsqqydcptwBfu26WW2cDm3u93bUzMbBJ8k3zNKFqxJ9ei2A==} + turbo-darwin-64@2.5.4: + resolution: {integrity: sha512-ah6YnH2dErojhFooxEzmvsoZQTMImaruZhFPfMKPBq8sb+hALRdvBNLqfc8NWlZq576FkfRZ/MSi4SHvVFT9PQ==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.5.6: - resolution: {integrity: sha512-LyiG+rD7JhMfYwLqB6k3LZQtYn8CQQUePbpA8mF/hMLPAekXdJo1g0bUPw8RZLwQXUIU/3BU7tXENvhSGz5DPA==} + turbo-darwin-arm64@2.5.4: + resolution: {integrity: sha512-2+Nx6LAyuXw2MdXb7pxqle3MYignLvS7OwtsP9SgtSBaMlnNlxl9BovzqdYAgkUW3AsYiQMJ/wBRb7d+xemM5A==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.5.6: - resolution: {integrity: sha512-GOcUTT0xiT/pSnHL4YD6Yr3HreUhU8pUcGqcI2ksIF9b2/r/kRHwGFcsHgpG3+vtZF/kwsP0MV8FTlTObxsYIA==} + turbo-linux-64@2.5.4: + resolution: {integrity: sha512-5May2kjWbc8w4XxswGAl74GZ5eM4Gr6IiroqdLhXeXyfvWEdm2mFYCSWOzz0/z5cAgqyGidF1jt1qzUR8hTmOA==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.5.6: - resolution: {integrity: sha512-10Tm15bruJEA3m0V7iZcnQBpObGBcOgUcO+sY7/2vk1bweW34LMhkWi8svjV9iDF68+KJDThnYDlYE/bc7/zzQ==} + turbo-linux-arm64@2.5.4: + resolution: {integrity: sha512-/2yqFaS3TbfxV3P5yG2JUI79P7OUQKOUvAnx4MV9Bdz6jqHsHwc9WZPpO4QseQm+NvmgY6ICORnoVPODxGUiJg==} cpu: [arm64] os: [linux] - turbo-windows-64@2.5.6: - resolution: {integrity: sha512-FyRsVpgaj76It0ludwZsNN40ytHN+17E4PFJyeliBEbxrGTc5BexlXVpufB7XlAaoaZVxbS6KT8RofLfDRyEPg==} + turbo-windows-64@2.5.4: + resolution: {integrity: sha512-EQUO4SmaCDhO6zYohxIjJpOKRN3wlfU7jMAj3CgcyTPvQR/UFLEKAYHqJOnJtymbQmiiM/ihX6c6W6Uq0yC7mA==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.5.6: - resolution: {integrity: sha512-j/tWu8cMeQ7HPpKri6jvKtyXg9K1gRyhdK4tKrrchH8GNHscPX/F71zax58yYtLRWTiK04zNzPcUJuoS0+v/+Q==} + turbo-windows-arm64@2.5.4: + resolution: {integrity: sha512-oQ8RrK1VS8lrxkLriotFq+PiF7iiGgkZtfLKF4DDKsmdbPo0O9R2mQxm7jHLuXraRCuIQDWMIw6dpcr7Iykf4A==} cpu: [arm64] os: [win32] - turbo@2.5.6: - resolution: {integrity: sha512-gxToHmi9oTBNB05UjUsrWf0OyN5ZXtD0apOarC1KIx232Vp3WimRNy3810QzeNSgyD5rsaIDXlxlbnOzlouo+w==} + turbo@2.5.4: + resolution: {integrity: sha512-kc8ZibdRcuWUG1pbYSBFWqmIjynlD8Lp7IB6U3vIzvOv9VG+6Sp8bzyeBWE3Oi8XV5KsQrznyRTBPvrf99E4mA==} hasBin: true type-check@0.4.0: @@ -5486,8 +5472,8 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript@5.9.2: - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true @@ -5507,8 +5493,8 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.15.0: - resolution: {integrity: sha512-Xyn5T99wU4kPhLZMm+ElE6M+IoSeG8Se7eG9xoZ82ZgVHJ07wb/IWcDZeXe2GOPkavcJ8ko5oSlXMDRl/QgY9Q==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} unicode-canonical-property-names-ecmascript@2.0.1: resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} @@ -5530,11 +5516,11 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unrs-resolver@1.11.1: - resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + unrs-resolver@1.9.2: + resolution: {integrity: sha512-VUyWiTNQD7itdiMuJy+EuLEErLj3uwX/EpHQF8EOf33Dq3Ju6VW1GXm+swk6+1h7a49uv9fKZ+dft9jU7esdLA==} - unstorage@1.17.0: - resolution: {integrity: sha512-l9Z7lBiwtNp8ZmcoZ/dmPkFXFdtEdZtTZafCSnEIj3YvtkXeGAtL2rN8MQFy/0cs4eOLpuRJMp9ivdug7TCvww==} + unstorage@1.16.0: + resolution: {integrity: sha512-WQ37/H5A7LcRPWfYOrDa1Ys02xAbpPJq6q5GkO88FBXVSQzHd7+BjEwfRqyaSWCv9MbsJy058GWjjPjcJ16GGA==} peerDependencies: '@azure/app-configuration': ^1.8.0 '@azure/cosmos': ^4.2.0 @@ -5544,11 +5530,10 @@ packages: '@azure/storage-blob': ^12.26.0 '@capacitor/preferences': ^6.0.3 || ^7.0.0 '@deno/kv': '>=0.9.0' - '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 '@planetscale/database': ^1.19.0 '@upstash/redis': ^1.34.3 '@vercel/blob': '>=0.27.1' - '@vercel/functions': ^2.2.12 '@vercel/kv': ^1.0.1 aws4fetch: ^1.0.20 db0: '>=0.2.1' @@ -5580,8 +5565,6 @@ packages: optional: true '@vercel/blob': optional: true - '@vercel/functions': - optional: true '@vercel/kv': optional: true aws4fetch: @@ -5660,8 +5643,8 @@ packages: typescript: optional: true - viem@2.37.3: - resolution: {integrity: sha512-hwoZqkFSy13GCFzIftgfIH8hNENvdlcHIvtLt73w91tL6rKmZjQisXWTahi1Vn5of8/JQ1FBKfwUus3YkDXwbw==} + viem@2.31.4: + resolution: {integrity: sha512-0UZ/asvzl6p44CIBRDbwEcn3HXIQQurBZcMo5qmLhQ8s27Ockk+RYohgTLlpLvkYs8/t4UUEREAbHLuek1kXcw==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -5721,6 +5704,12 @@ packages: yaml: optional: true + vitest-mock-extended@3.1.0: + resolution: {integrity: sha512-vCM0VkuocOUBwwqwV7JB7YStw07pqeKvEIrZnR8l3PtwYi6rAAJAyJACeC1UYNfbQWi85nz7EdiXWBFI5hll2g==} + peerDependencies: + typescript: 3.x || 4.x || 5.x + vitest: '>=3.0.0' + vitest@3.2.4: resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -5753,8 +5742,8 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - wagmi@2.16.9: - resolution: {integrity: sha512-5NbjvuNNhT0t0lQsDD5otQqZ5RZBM1UhInHoBq/Lpnr6xLLa8AWxYqHg5oZtGCdiUNltys11iBOS6z4mLepIqw==} + wagmi@2.15.6: + resolution: {integrity: sha512-tR4tm+7eE0UloQe1oi4hUIjIDyjv5ImQlzq/QcvvfJYWF/EquTfGrmht6+nTYGCIeSzeEvbK90KgWyNqa+HD7Q==} peerDependencies: '@tanstack/react-query': '>=5.0.0' react: '>=18' @@ -5879,8 +5868,8 @@ packages: utf-8-validate: optional: true - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + ws@8.18.2: + resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -5915,8 +5904,8 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + yaml@2.8.0: + resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} engines: {node: '>= 14.6'} hasBin: true @@ -5935,8 +5924,8 @@ packages: zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@3.25.67: + resolution: {integrity: sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==} zustand@5.0.0: resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} @@ -5956,24 +5945,6 @@ packages: use-sync-external-store: optional: true - 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: '@adraffy/ens-normalize@1.11.0': {} @@ -5982,13 +5953,13 @@ snapshots: '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 '@asamuzakjp/css-color@3.2.0': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 lru-cache: 10.4.3 @@ -5999,20 +5970,20 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.0': {} + '@babel/compat-data@7.27.5': {} - '@babel/core@7.28.3': + '@babel/core@7.27.4': dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 + '@babel/generator': 7.27.5 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) - '@babel/helpers': 7.28.3 - '@babel/parser': 7.28.3 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) + '@babel/helpers': 7.27.6 + '@babel/parser': 7.27.5 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 convert-source-map: 2.0.0 debug: 4.4.1 gensync: 1.0.0-beta.2 @@ -6021,49 +5992,49 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.28.3': + '@babel/generator@7.27.5': dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.27.6 '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.28.0 + '@babel/compat-data': 7.27.5 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.25.4 + browserslist: 4.25.0 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.3)': + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.4) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.27.4 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.3)': + '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 regexpu-core: 6.2.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.3)': + '@babel/helper-define-polyfill-provider@0.6.4(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 debug: 4.4.1 @@ -6072,59 +6043,57 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-globals@7.28.0': {} - '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.3)': + '@babel/helper-module-transforms@7.27.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.27.6 '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.3)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-wrap-function': 7.28.3 - '@babel/traverse': 7.28.3 + '@babel/helper-wrap-function': 7.27.1 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.3)': + '@babel/helper-replace-supers@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color @@ -6134,629 +6103,613 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helper-wrap-function@7.28.3': + '@babel/helper-wrap-function@7.27.1': dependencies: '@babel/template': 7.27.2 - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color - '@babel/helpers@7.28.3': + '@babel/helpers@7.27.6': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.2 + '@babel/types': 7.27.6 - '@babel/parser@7.28.3': + '@babel/parser@7.27.5': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.27.6 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.3)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.3)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 - '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.3)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-async-generator-functions@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.3) - '@babel/traverse': 7.28.3 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.27.4) + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.3) + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-block-scoping@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-block-scoping@7.27.5(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.3)': + '@babel/plugin-transform-class-static-block@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.28.3(@babel/core@7.28.3)': + '@babel/plugin-transform-classes@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-globals': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) - '@babel/traverse': 7.28.3 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.4) + '@babel/traverse': 7.27.4 + globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/template': 7.27.2 - '@babel/plugin-transform-destructuring@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-destructuring@7.27.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.3)': - dependencies: - '@babel/core': 7.28.3 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-object-rest-spread@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-object-rest-spread@7.27.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.3) - '@babel/traverse': 7.28.3 - transitivePeerDependencies: - - supports-color + '@babel/plugin-transform-destructuring': 7.27.3(@babel/core@7.27.4) + '@babel/plugin-transform-parameters': 7.27.1(@babel/core@7.27.4) - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.3)': + '@babel/plugin-transform-parameters@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-react-display-name@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) - '@babel/types': 7.28.2 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.4) + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regenerator@7.28.3(@babel/core@7.28.3)': + '@babel/plugin-transform-regenerator@7.27.5(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.3)': + '@babel/plugin-transform-typescript@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) '@babel/helper-plugin-utils': 7.27.1 - '@babel/preset-env@7.28.3(@babel/core@7.28.3)': + '@babel/preset-env@7.27.2(@babel/core@7.27.4)': dependencies: - '@babel/compat-data': 7.28.0 - '@babel/core': 7.28.3 + '@babel/compat-data': 7.27.5 + '@babel/core': 7.27.4 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.3) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.3) - '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.3) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-block-scoping': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.3) - '@babel/plugin-transform-classes': 7.28.3(@babel/core@7.28.3) - '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-object-rest-spread': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.3) - '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-regenerator': 7.28.3(@babel/core@7.28.3) - '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.3) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.3) - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.3) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.3) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.3) - core-js-compat: 3.45.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.27.4) + '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.27.4) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-async-generator-functions': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-block-scoping': 7.27.5(@babel/core@7.27.4) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-class-static-block': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-classes': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-destructuring': 7.27.3(@babel/core@7.27.4) + '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-object-rest-spread': 7.27.3(@babel/core@7.27.4) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-parameters': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-regenerator': 7.27.5(@babel/core@7.27.4) + '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.27.4) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.27.4) + babel-plugin-polyfill-corejs2: 0.4.13(@babel/core@7.27.4) + babel-plugin-polyfill-corejs3: 0.11.1(@babel/core@7.27.4) + babel-plugin-polyfill-regenerator: 0.6.4(@babel/core@7.27.4) + core-js-compat: 3.43.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.3)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/types': 7.28.2 + '@babel/types': 7.27.6 esutils: 2.0.3 - '@babel/preset-react@7.27.1(@babel/core@7.28.3)': + '@babel/preset-react@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-react-display-name': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.27.1(@babel/core@7.28.3)': + '@babel/preset-typescript@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/runtime@7.28.3': {} + '@babel/runtime@7.27.6': {} '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 - '@babel/traverse@7.28.3': + '@babel/traverse@7.27.4': dependencies: '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.3 + '@babel/generator': 7.27.5 + '@babel/parser': 7.27.5 '@babel/template': 7.27.2 - '@babel/types': 7.28.2 + '@babel/types': 7.27.6 debug: 4.4.1 + globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.28.2': + '@babel/types@7.27.6': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@base-org/account@1.1.1(@types/react@19.1.12)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/cdp-sdk@1.22.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: - '@noble/hashes': 1.4.0 - clsx: 1.2.1 - eventemitter3: 5.0.1 - idb-keyval: 6.2.1 - ox: 0.6.9(typescript@5.9.2)(zod@3.25.76) - preact: 10.24.2 - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.3(@types/react@19.1.12)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + abitype: 1.0.6(typescript@5.8.3)(zod@3.25.67) + axios: 1.10.0 + jose: 6.0.11 + md5: 2.3.0 + uncrypto: 0.1.3 + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + zod: 3.25.67 transitivePeerDependencies: - - '@types/react' - bufferutil - - immer - - react + - debug + - encoding + - fastestsmallesttextencoderdecoder - typescript - - use-sync-external-store - utf-8-validate - - zod - '@coinbase/cdp-sdk@1.36.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@coinbase/cdp-sdk@1.38.2(bufferutil@4.0.9)(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.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - abitype: 1.0.6(typescript@5.9.2)(zod@3.25.76) - axios: 1.11.0 - axios-retry: 4.5.0(axios@1.11.0) - jose: 6.1.0 + '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + abitype: 1.0.6(typescript@5.8.3)(zod@3.25.67) + 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.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zod: 3.25.76 + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + zod: 3.25.67 transitivePeerDependencies: - bufferutil - debug @@ -6765,21 +6718,21 @@ snapshots: - typescript - utf-8-validate - '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/onchainkit@0.38.15(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(bufferutil@4.0.9)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: - '@farcaster/frame-sdk': 0.1.9(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.20.3(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@tanstack/react-query': 5.85.9(react@19.1.1) - '@wagmi/core': 2.20.3(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@farcaster/frame-sdk': 0.0.60(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@farcaster/frame-wagmi-connector': 0.0.53(@farcaster/frame-sdk@0.0.60(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67))(@wagmi/core@2.17.3(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)) + '@tanstack/react-query': 5.81.2(react@19.1.0) + '@wagmi/core': 2.17.3(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)) clsx: 2.1.1 graphql: 16.11.0 graphql-request: 6.1.0(graphql@16.11.0) qrcode: 1.5.4 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) tailwind-merge: 2.6.0 - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.16.9(@tanstack/query-core@5.85.9)(@tanstack/react-query@5.85.9(react@19.1.1))(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + wagmi: 2.15.6(@tanstack/query-core@5.81.2)(@tanstack/react-query@5.81.2(react@19.1.0))(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67))(zod@3.25.67) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6789,7 +6742,6 @@ snapshots: - '@azure/storage-blob' - '@capacitor/preferences' - '@deno/kv' - - '@farcaster/miniapp-sdk' - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' @@ -6797,7 +6749,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -6821,34 +6772,21 @@ snapshots: eth-json-rpc-filters: 6.0.1 eventemitter3: 5.0.1 keccak: 3.0.4 - preact: 10.27.1 - sha.js: 2.4.12 + preact: 10.26.9 + sha.js: 2.4.11 transitivePeerDependencies: - supports-color - '@coinbase/wallet-sdk@4.3.6(@types/react@19.1.12)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/wallet-sdk@4.3.3': dependencies: - '@noble/hashes': 1.4.0 + '@noble/hashes': 1.8.0 clsx: 1.2.1 eventemitter3: 5.0.1 - idb-keyval: 6.2.1 - ox: 0.6.9(typescript@5.9.2)(zod@3.25.76) - preact: 10.24.2 - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.3(@types/react@19.1.12)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) - transitivePeerDependencies: - - '@types/react' - - bufferutil - - immer - - react - - typescript - - use-sync-external-store - - utf-8-validate - - zod + preact: 10.26.9 - '@craftamap/esbuild-plugin-html@0.9.0(bufferutil@4.0.9)(esbuild@0.25.9)(utf-8-validate@5.0.10)': + '@craftamap/esbuild-plugin-html@0.9.0(bufferutil@4.0.9)(esbuild@0.25.5)(utf-8-validate@5.0.10)': dependencies: - esbuild: 0.25.9 + esbuild: 0.25.5 jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) lodash: 4.17.21 transitivePeerDependencies: @@ -6857,16 +6795,16 @@ snapshots: - supports-color - utf-8-validate - '@csstools/color-helpers@5.1.0': {} + '@csstools/color-helpers@5.0.2': {} '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': dependencies: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + '@csstools/css-color-parser@3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': dependencies: - '@csstools/color-helpers': 5.1.0 + '@csstools/color-helpers': 5.0.2 '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 @@ -6877,22 +6815,22 @@ snapshots: '@csstools/css-tokenizer@3.0.4': {} - '@ecies/ciphers@0.2.4(@noble/ciphers@1.3.0)': + '@ecies/ciphers@0.2.3(@noble/ciphers@1.3.0)': dependencies: '@noble/ciphers': 1.3.0 - '@emnapi/core@1.5.0': + '@emnapi/core@1.4.3': dependencies: - '@emnapi/wasi-threads': 1.1.0 + '@emnapi/wasi-threads': 1.0.2 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.5.0': + '@emnapi/runtime@1.4.3': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.1.0': + '@emnapi/wasi-threads@1.0.2': dependencies: tslib: 2.8.1 optional: true @@ -6900,97 +6838,94 @@ snapshots: '@es-joy/jsdoccomment@0.50.2': dependencies: '@types/estree': 1.0.8 - '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/types': 8.35.0 comment-parser: 1.4.1 esquery: 1.6.0 jsdoc-type-pratt-parser: 4.1.0 - '@esbuild/aix-ppc64@0.25.9': + '@esbuild/aix-ppc64@0.25.5': optional: true - '@esbuild/android-arm64@0.25.9': + '@esbuild/android-arm64@0.25.5': optional: true - '@esbuild/android-arm@0.25.9': + '@esbuild/android-arm@0.25.5': optional: true - '@esbuild/android-x64@0.25.9': + '@esbuild/android-x64@0.25.5': optional: true - '@esbuild/darwin-arm64@0.25.9': + '@esbuild/darwin-arm64@0.25.5': optional: true - '@esbuild/darwin-x64@0.25.9': + '@esbuild/darwin-x64@0.25.5': optional: true - '@esbuild/freebsd-arm64@0.25.9': + '@esbuild/freebsd-arm64@0.25.5': optional: true - '@esbuild/freebsd-x64@0.25.9': + '@esbuild/freebsd-x64@0.25.5': optional: true - '@esbuild/linux-arm64@0.25.9': + '@esbuild/linux-arm64@0.25.5': optional: true - '@esbuild/linux-arm@0.25.9': + '@esbuild/linux-arm@0.25.5': optional: true - '@esbuild/linux-ia32@0.25.9': + '@esbuild/linux-ia32@0.25.5': optional: true - '@esbuild/linux-loong64@0.25.9': + '@esbuild/linux-loong64@0.25.5': optional: true - '@esbuild/linux-mips64el@0.25.9': + '@esbuild/linux-mips64el@0.25.5': optional: true - '@esbuild/linux-ppc64@0.25.9': + '@esbuild/linux-ppc64@0.25.5': optional: true - '@esbuild/linux-riscv64@0.25.9': + '@esbuild/linux-riscv64@0.25.5': optional: true - '@esbuild/linux-s390x@0.25.9': + '@esbuild/linux-s390x@0.25.5': optional: true - '@esbuild/linux-x64@0.25.9': + '@esbuild/linux-x64@0.25.5': optional: true - '@esbuild/netbsd-arm64@0.25.9': + '@esbuild/netbsd-arm64@0.25.5': optional: true - '@esbuild/netbsd-x64@0.25.9': + '@esbuild/netbsd-x64@0.25.5': optional: true - '@esbuild/openbsd-arm64@0.25.9': + '@esbuild/openbsd-arm64@0.25.5': optional: true - '@esbuild/openbsd-x64@0.25.9': + '@esbuild/openbsd-x64@0.25.5': optional: true - '@esbuild/openharmony-arm64@0.25.9': + '@esbuild/sunos-x64@0.25.5': optional: true - '@esbuild/sunos-x64@0.25.9': + '@esbuild/win32-arm64@0.25.5': optional: true - '@esbuild/win32-arm64@0.25.9': + '@esbuild/win32-ia32@0.25.5': optional: true - '@esbuild/win32-ia32@0.25.9': + '@esbuild/win32-x64@0.25.5': optional: true - '@esbuild/win32-x64@0.25.9': - optional: true - - '@eslint-community/eslint-utils@4.8.0(eslint@9.34.0(jiti@1.21.7))': + '@eslint-community/eslint-utils@4.7.0(eslint@9.29.0(jiti@1.21.7))': dependencies: - eslint: 9.34.0(jiti@1.21.7) + eslint: 9.29.0(jiti@1.21.7) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/config-array@0.21.0': + '@eslint/config-array@0.20.1': dependencies: '@eslint/object-schema': 2.1.6 debug: 4.4.1 @@ -6998,9 +6933,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.3.1': {} + '@eslint/config-helpers@0.2.3': {} - '@eslint/core@0.15.2': + '@eslint/core@0.14.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/core@0.15.0': dependencies: '@types/json-schema': 7.0.15 @@ -7018,13 +6957,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.34.0': {} + '@eslint/js@9.29.0': {} '@eslint/object-schema@2.1.6': {} - '@eslint/plugin-kit@0.3.5': + '@eslint/plugin-kit@0.3.2': dependencies: - '@eslint/core': 0.15.2 + '@eslint/core': 0.15.0 levn: 0.4.1 '@ethereumjs/common@3.2.0': @@ -7047,38 +6986,24 @@ snapshots: ethereum-cryptography: 2.2.1 micro-ftch: 0.3.1 - '@farcaster/frame-sdk@0.1.9(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - dependencies: - '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@farcaster/quick-auth': 0.0.6(typescript@5.9.2) - comlink: 4.4.2 - eventemitter3: 5.0.1 - ox: 0.4.4(typescript@5.9.2)(zod@3.25.76) - transitivePeerDependencies: - - bufferutil - - encoding - - typescript - - utf-8-validate - - zod - - '@farcaster/miniapp-core@0.3.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@farcaster/frame-core@0.1.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - ox: 0.4.4(typescript@5.9.2)(zod@3.25.76) - zod: 3.25.76 + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + ox: 0.4.4(typescript@5.8.3)(zod@3.25.67) + zod: 3.25.67 transitivePeerDependencies: - bufferutil - encoding - typescript - utf-8-validate - '@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@farcaster/frame-sdk@0.0.60(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: - '@farcaster/miniapp-core': 0.3.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@farcaster/quick-auth': 0.0.6(typescript@5.9.2) + '@farcaster/frame-core': 0.1.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@farcaster/quick-auth': 0.0.5(typescript@5.8.3) comlink: 4.4.2 eventemitter3: 5.0.1 - ox: 0.4.4(typescript@5.9.2)(zod@3.25.76) + ox: 0.4.4(typescript@5.8.3)(zod@3.25.67) transitivePeerDependencies: - bufferutil - encoding @@ -7086,133 +7011,122 @@ snapshots: - utf-8-validate - zod - '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.20.3(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@farcaster/frame-wagmi-connector@0.0.53(@farcaster/frame-sdk@0.0.60(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67))(@wagmi/core@2.17.3(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67))': dependencies: - '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.20.3(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/frame-sdk': 0.0.60(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@wagmi/core': 2.17.3(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)) + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) - '@farcaster/quick-auth@0.0.6(typescript@5.9.2)': + '@farcaster/quick-auth@0.0.5(typescript@5.8.3)': dependencies: jose: 5.10.0 - typescript: 5.9.2 - zod: 3.25.76 - - '@gemini-wallet/core@0.2.0(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': - dependencies: - '@metamask/rpc-errors': 7.0.2 - eventemitter3: 5.0.1 - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - transitivePeerDependencies: - - supports-color + typescript: 5.8.3 + zod: 3.25.67 '@graphql-typed-document-node/core@3.2.0(graphql@16.11.0)': dependencies: graphql: 16.11.0 - '@heroicons/react@2.2.0(react@19.1.1)': + '@heroicons/react@2.2.0(react@19.1.0)': dependencies: - react: 19.1.1 + react: 19.1.0 - '@hono/node-server@1.19.1(hono@4.9.6)': + '@hono/node-server@1.14.4(hono@4.8.2)': dependencies: - hono: 4.9.6 + hono: 4.8.2 '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.7': + '@humanfs/node@0.16.6': dependencies: '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.4.3 + '@humanwhocodes/retry': 0.3.1 '@humanwhocodes/module-importer@1.0.1': {} + '@humanwhocodes/retry@0.3.1': {} + '@humanwhocodes/retry@0.4.3': {} - '@img/sharp-darwin-arm64@0.34.3': + '@img/sharp-darwin-arm64@0.34.2': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.0 + '@img/sharp-libvips-darwin-arm64': 1.1.0 optional: true - '@img/sharp-darwin-x64@0.34.3': + '@img/sharp-darwin-x64@0.34.2': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.0 + '@img/sharp-libvips-darwin-x64': 1.1.0 optional: true - '@img/sharp-libvips-darwin-arm64@1.2.0': + '@img/sharp-libvips-darwin-arm64@1.1.0': optional: true - '@img/sharp-libvips-darwin-x64@1.2.0': + '@img/sharp-libvips-darwin-x64@1.1.0': optional: true - '@img/sharp-libvips-linux-arm64@1.2.0': + '@img/sharp-libvips-linux-arm64@1.1.0': optional: true - '@img/sharp-libvips-linux-arm@1.2.0': + '@img/sharp-libvips-linux-arm@1.1.0': optional: true - '@img/sharp-libvips-linux-ppc64@1.2.0': + '@img/sharp-libvips-linux-ppc64@1.1.0': optional: true - '@img/sharp-libvips-linux-s390x@1.2.0': + '@img/sharp-libvips-linux-s390x@1.1.0': optional: true - '@img/sharp-libvips-linux-x64@1.2.0': + '@img/sharp-libvips-linux-x64@1.1.0': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.2.0': + '@img/sharp-libvips-linuxmusl-x64@1.1.0': optional: true - '@img/sharp-linux-arm64@0.34.3': + '@img/sharp-linux-arm64@0.34.2': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.0 + '@img/sharp-libvips-linux-arm64': 1.1.0 optional: true - '@img/sharp-linux-arm@0.34.3': + '@img/sharp-linux-arm@0.34.2': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.0 + '@img/sharp-libvips-linux-arm': 1.1.0 optional: true - '@img/sharp-linux-ppc64@0.34.3': + '@img/sharp-linux-s390x@0.34.2': optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.0 + '@img/sharp-libvips-linux-s390x': 1.1.0 optional: true - '@img/sharp-linux-s390x@0.34.3': + '@img/sharp-linux-x64@0.34.2': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.0 + '@img/sharp-libvips-linux-x64': 1.1.0 optional: true - '@img/sharp-linux-x64@0.34.3': + '@img/sharp-linuxmusl-arm64@0.34.2': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 optional: true - '@img/sharp-linuxmusl-arm64@0.34.3': + '@img/sharp-linuxmusl-x64@0.34.2': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 optional: true - '@img/sharp-linuxmusl-x64@0.34.3': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.0 - optional: true - - '@img/sharp-wasm32@0.34.3': + '@img/sharp-wasm32@0.34.2': dependencies: - '@emnapi/runtime': 1.5.0 + '@emnapi/runtime': 1.4.3 optional: true - '@img/sharp-win32-arm64@0.34.3': + '@img/sharp-win32-arm64@0.34.2': optional: true - '@img/sharp-win32-ia32@0.34.3': + '@img/sharp-win32-ia32@0.34.2': optional: true - '@img/sharp-win32-x64@0.34.3': + '@img/sharp-win32-x64@0.34.2': optional: true '@isaacs/cliui@8.0.2': @@ -7224,25 +7138,28 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@jridgewell/gen-mapping@0.3.13': + '@jridgewell/gen-mapping@0.3.8': dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/set-array@1.2.1': {} - '@jridgewell/trace-mapping@0.3.30': + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.5.0 - '@lit-labs/ssr-dom-shim@1.4.0': {} + '@lit-labs/ssr-dom-shim@1.3.0': {} - '@lit/reactive-element@2.1.1': + '@lit/reactive-element@2.1.0': dependencies: - '@lit-labs/ssr-dom-shim': 1.4.0 + '@lit-labs/ssr-dom-shim': 1.3.0 '@metamask/eth-json-rpc-provider@1.0.1': dependencies: @@ -7284,7 +7201,7 @@ snapshots: '@metamask/onboarding@1.0.1': dependencies: - bowser: 2.12.1 + bowser: 2.11.0 '@metamask/providers@16.1.0': dependencies: @@ -7310,13 +7227,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@metamask/rpc-errors@7.0.2': - dependencies: - '@metamask/utils': 11.7.0 - fast-safe-stringify: 2.1.1 - transitivePeerDependencies: - - supports-color - '@metamask/safe-event-emitter@2.0.0': {} '@metamask/safe-event-emitter@3.1.2': {} @@ -7342,13 +7252,13 @@ snapshots: '@metamask/sdk@0.32.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.27.6 '@metamask/onboarding': 1.0.1 '@metamask/providers': 16.1.0 '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0)(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@metamask/sdk-install-modal-web': 0.32.0 '@paulmillr/qr': 0.2.1 - bowser: 2.12.1 + bowser: 2.11.0 cross-fetch: 4.1.0 debug: 4.4.1 eciesjs: 0.4.15 @@ -7369,22 +7279,6 @@ snapshots: '@metamask/superstruct@3.2.1': {} - '@metamask/utils@11.7.0': - dependencies: - '@ethereumjs/tx': 4.2.0 - '@metamask/superstruct': 3.2.1 - '@noble/hashes': 1.8.0 - '@scure/base': 1.2.6 - '@types/debug': 4.1.12 - '@types/lodash': 4.17.20 - debug: 4.4.1 - lodash: 4.17.21 - pony-cause: 2.1.11 - semver: 7.7.2 - uuid: 9.0.1 - transitivePeerDependencies: - - supports-color - '@metamask/utils@5.0.2': dependencies: '@ethereumjs/tx': 4.2.0 @@ -7423,41 +7317,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@napi-rs/wasm-runtime@0.2.12': + '@napi-rs/wasm-runtime@0.2.11': dependencies: - '@emnapi/core': 1.5.0 - '@emnapi/runtime': 1.5.0 - '@tybys/wasm-util': 0.10.0 + '@emnapi/core': 1.4.3 + '@emnapi/runtime': 1.4.3 + '@tybys/wasm-util': 0.9.0 optional: true - '@next/env@15.5.2': {} + '@next/env@15.3.4': {} '@next/eslint-plugin-next@15.1.7': dependencies: fast-glob: 3.3.1 - '@next/swc-darwin-arm64@15.5.2': + '@next/swc-darwin-arm64@15.3.4': optional: true - '@next/swc-darwin-x64@15.5.2': + '@next/swc-darwin-x64@15.3.4': optional: true - '@next/swc-linux-arm64-gnu@15.5.2': + '@next/swc-linux-arm64-gnu@15.3.4': optional: true - '@next/swc-linux-arm64-musl@15.5.2': + '@next/swc-linux-arm64-musl@15.3.4': optional: true - '@next/swc-linux-x64-gnu@15.5.2': + '@next/swc-linux-x64-gnu@15.3.4': optional: true - '@next/swc-linux-x64-musl@15.5.2': + '@next/swc-linux-x64-musl@15.3.4': optional: true - '@next/swc-win32-arm64-msvc@15.5.2': + '@next/swc-win32-arm64-msvc@15.3.4': optional: true - '@next/swc-win32-x64-msvc@15.5.2': + '@next/swc-win32-x64-msvc@15.3.4': optional: true '@noble/ciphers@1.2.1': {} @@ -7476,11 +7370,7 @@ snapshots: dependencies: '@noble/hashes': 1.7.1 - '@noble/curves@1.9.1': - dependencies: - '@noble/hashes': 1.8.0 - - '@noble/curves@1.9.7': + '@noble/curves@1.9.2': dependencies: '@noble/hashes': 1.8.0 @@ -7511,37 +7401,37 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@pkgr/core@0.2.9': {} + '@pkgr/core@0.2.7': {} - '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) transitivePeerDependencies: - bufferutil - typescript - utf-8-validate - zod - '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) transitivePeerDependencies: - bufferutil - typescript - utf-8-validate - zod - '@reown/appkit-controllers@1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-controllers@1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 1.13.2(@types/react@19.1.12)(react@19.1.1) - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + valtio: 1.13.2(@types/react@19.1.8)(react@19.1.0) + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7557,7 +7447,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7570,14 +7459,14 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-pay@1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-pay@1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.12)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.8)(react@19.1.0))(zod@3.25.67) lit: 3.3.0 - valtio: 1.13.2(@types/react@19.1.12)(react@19.1.1) + valtio: 1.13.2(@types/react@19.1.8)(react@19.1.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7593,7 +7482,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7610,13 +7498,13 @@ snapshots: dependencies: buffer: 6.0.3 - '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.12)(react@19.1.1))(zod@3.25.76)': + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.8)(react@19.1.0))(zod@3.25.67)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.12)(react@19.1.1))(zod@3.25.76) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.8)(react@19.1.0))(zod@3.25.67) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) lit: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -7633,7 +7521,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7647,11 +7534,11 @@ snapshots: - valtio - zod - '@reown/appkit-ui@1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-ui@1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) lit: 3.3.0 qrcode: 1.5.3 transitivePeerDependencies: @@ -7669,7 +7556,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7682,16 +7568,16 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-utils@1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.12)(react@19.1.1))(zod@3.25.76)': + '@reown/appkit-utils@1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.8)(react@19.1.0))(zod@3.25.67)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 1.13.2(@types/react@19.1.12)(react@19.1.1) - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + valtio: 1.13.2(@types/react@19.1.8)(react@19.1.0) + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7707,7 +7593,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7720,9 +7605,9 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-wallet@1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@reown/appkit-wallet@1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) '@reown/appkit-polyfills': 1.7.8 '@walletconnect/logger': 2.1.2 zod: 3.22.4 @@ -7731,21 +7616,21 @@ snapshots: - typescript - utf-8-validate - '@reown/appkit@1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit@1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-pay': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-pay': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.12)(react@19.1.1))(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.12)(react@19.1.1))(zod@3.25.76) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.21.0(@vercel/functions@2.2.13) - '@walletconnect/universal-provider': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.8)(react@19.1.0))(zod@3.25.67) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.8)(react@19.1.0))(zod@3.25.67) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@walletconnect/types': 2.21.0 + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) bs58: 6.0.0 - valtio: 1.13.2(@types/react@19.1.12)(react@19.1.1) - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.1.8)(react@19.1.0) + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7761,7 +7646,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7774,76 +7658,73 @@ snapshots: - utf-8-validate - zod - '@rollup/rollup-android-arm-eabi@4.50.0': + '@rollup/rollup-android-arm-eabi@4.44.0': optional: true - '@rollup/rollup-android-arm64@4.50.0': + '@rollup/rollup-android-arm64@4.44.0': optional: true - '@rollup/rollup-darwin-arm64@4.50.0': + '@rollup/rollup-darwin-arm64@4.44.0': optional: true - '@rollup/rollup-darwin-x64@4.50.0': + '@rollup/rollup-darwin-x64@4.44.0': optional: true - '@rollup/rollup-freebsd-arm64@4.50.0': + '@rollup/rollup-freebsd-arm64@4.44.0': optional: true - '@rollup/rollup-freebsd-x64@4.50.0': + '@rollup/rollup-freebsd-x64@4.44.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.50.0': + '@rollup/rollup-linux-arm-gnueabihf@4.44.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.50.0': + '@rollup/rollup-linux-arm-musleabihf@4.44.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.50.0': + '@rollup/rollup-linux-arm64-gnu@4.44.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.50.0': + '@rollup/rollup-linux-arm64-musl@4.44.0': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.50.0': + '@rollup/rollup-linux-loongarch64-gnu@4.44.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.50.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.44.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.50.0': + '@rollup/rollup-linux-riscv64-gnu@4.44.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.50.0': + '@rollup/rollup-linux-riscv64-musl@4.44.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.50.0': + '@rollup/rollup-linux-s390x-gnu@4.44.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.50.0': + '@rollup/rollup-linux-x64-gnu@4.44.0': optional: true - '@rollup/rollup-linux-x64-musl@4.50.0': + '@rollup/rollup-linux-x64-musl@4.44.0': optional: true - '@rollup/rollup-openharmony-arm64@4.50.0': + '@rollup/rollup-win32-arm64-msvc@4.44.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.50.0': + '@rollup/rollup-win32-ia32-msvc@4.44.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.50.0': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.50.0': + '@rollup/rollup-win32-x64-msvc@4.44.0': optional: true '@rtsao/scc@1.1.0': {} - '@rushstack/eslint-patch@1.12.0': {} + '@rushstack/eslint-patch@1.11.0': {} - '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) events: 3.3.0 transitivePeerDependencies: - bufferutil @@ -7851,10 +7732,10 @@ snapshots: - utf-8-validate - zod - '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) transitivePeerDependencies: - bufferutil - typescript @@ -7881,7 +7762,7 @@ snapshots: '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 @@ -7902,53 +7783,53 @@ 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.9.2)(ws@8.18.0(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.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@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.9.2)(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.9.2))': + '@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.9.2)(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.9.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) - '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(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.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@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/accounts@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/accounts@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec': 2.3.0(typescript@5.9.2) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 2.3.0(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/rpc-spec': 2.3.0(typescript@5.8.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/addresses@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/addresses@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/assertions': 2.3.0(typescript@5.9.2) - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/nominal-types': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/assertions': 2.3.0(typescript@5.8.3) + '@solana/codecs-core': 2.3.0(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/nominal-types': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/assertions@2.3.0(typescript@5.9.2)': + '@solana/assertions@2.3.0(typescript@5.8.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/errors': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 - '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) bigint-buffer: 1.1.5 - bignumber.js: 9.3.1 + bignumber.js: 9.3.0 transitivePeerDependencies: - bufferutil - encoding @@ -7959,394 +7840,463 @@ snapshots: dependencies: buffer: 6.0.3 - '@solana/codecs-core@2.0.0-rc.1(typescript@5.9.2)': + '@solana/codecs-core@2.0.0-rc.1(typescript@5.8.3)': + dependencies: + '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) + typescript: 5.8.3 + + '@solana/codecs-core@2.1.1(typescript@5.8.3)': + dependencies: + '@solana/errors': 2.1.1(typescript@5.8.3) + typescript: 5.8.3 + + '@solana/codecs-core@2.3.0(typescript@5.8.3)': dependencies: - '@solana/errors': 2.0.0-rc.1(typescript@5.9.2) - typescript: 5.9.2 + '@solana/errors': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 - '@solana/codecs-core@2.3.0(typescript@5.9.2)': + '@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.8.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) + '@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 - '@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.9.2)': + '@solana/codecs-data-structures@2.3.0(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.9.2) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.9.2) - '@solana/errors': 2.0.0-rc.1(typescript@5.9.2) - typescript: 5.9.2 + '@solana/codecs-core': 2.3.0(typescript@5.8.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.8.3) + '@solana/errors': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 - '@solana/codecs-data-structures@2.3.0(typescript@5.9.2)': + '@solana/codecs-numbers@2.0.0-rc.1(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/codecs-numbers': 2.3.0(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@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 - '@solana/codecs-numbers@2.0.0-rc.1(typescript@5.9.2)': + '@solana/codecs-numbers@2.1.1(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.9.2) - '@solana/errors': 2.0.0-rc.1(typescript@5.9.2) - typescript: 5.9.2 + '@solana/codecs-core': 2.1.1(typescript@5.8.3) + '@solana/errors': 2.1.1(typescript@5.8.3) + typescript: 5.8.3 - '@solana/codecs-numbers@2.3.0(typescript@5.9.2)': + '@solana/codecs-numbers@2.3.0(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/codecs-core': 2.3.0(typescript@5.8.3) + '@solana/errors': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 - '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.9.2) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.9.2) - '@solana/errors': 2.0.0-rc.1(typescript@5.9.2) + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.8.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) fastestsmallesttextencoderdecoder: 1.0.22 - typescript: 5.9.2 + typescript: 5.8.3 - '@solana/codecs-strings@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/codecs-strings@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/codecs-numbers': 2.3.0(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) + '@solana/codecs-core': 2.3.0(typescript@5.8.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.8.3) + '@solana/errors': 2.3.0(typescript@5.8.3) fastestsmallesttextencoderdecoder: 1.0.22 - typescript: 5.9.2 + typescript: 5.8.3 - '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.9.2) - '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.9.2) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.9.2) - '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/codecs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/codecs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/codecs-data-structures': 2.3.0(typescript@5.9.2) - '@solana/codecs-numbers': 2.3.0(typescript@5.9.2) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/options': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@solana/codecs-core': 2.3.0(typescript@5.8.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.8.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.8.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/options': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/errors@2.0.0-rc.1(typescript@5.9.2)': + '@solana/errors@2.0.0-rc.1(typescript@5.8.3)': dependencies: - chalk: 5.6.0 + chalk: 5.4.1 commander: 12.1.0 - typescript: 5.9.2 + typescript: 5.8.3 - '@solana/errors@2.3.0(typescript@5.9.2)': + '@solana/errors@2.1.1(typescript@5.8.3)': dependencies: - chalk: 5.6.0 - commander: 14.0.0 - typescript: 5.9.2 + chalk: 5.4.1 + commander: 13.1.0 + typescript: 5.8.3 - '@solana/fast-stable-stringify@2.3.0(typescript@5.9.2)': + '@solana/errors@2.3.0(typescript@5.8.3)': dependencies: - typescript: 5.9.2 + chalk: 5.4.1 + commander: 14.0.1 + typescript: 5.8.3 - '@solana/functional@2.3.0(typescript@5.9.2)': + '@solana/fast-stable-stringify@2.3.0(typescript@5.8.3)': dependencies: - typescript: 5.9.2 + typescript: 5.8.3 - '@solana/instructions@2.3.0(typescript@5.9.2)': + '@solana/functional@2.3.0(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + typescript: 5.8.3 - '@solana/keys@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/instructions@2.3.0(typescript@5.8.3)': dependencies: - '@solana/assertions': 2.3.0(typescript@5.9.2) - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/nominal-types': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/codecs-core': 2.3.0(typescript@5.8.3) + '@solana/errors': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 + + '@solana/keys@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/assertions': 2.3.0(typescript@5.8.3) + '@solana/codecs-core': 2.3.0(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/nominal-types': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(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.9.2) - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/functional': 2.3.0(typescript@5.9.2) - '@solana/instructions': 2.3.0(typescript@5.9.2) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/programs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-parsed-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/signers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.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/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.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/functional': 2.3.0(typescript@5.9.2) - '@solana/instructions': 2.3.0(typescript@5.9.2) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/programs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-parsed-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/signers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.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))': + 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@8.18.0(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@8.18.0(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/nominal-types@2.3.0(typescript@5.9.2)': + '@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.2(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@8.18.2(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@8.18.2(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/nominal-types@2.3.0(typescript@5.8.3)': dependencies: - typescript: 5.9.2 + typescript: 5.8.3 - '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.9.2) - '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.9.2) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.9.2) - '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.0.0-rc.1(typescript@5.9.2) - typescript: 5.9.2 + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/options@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/options@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/codecs-data-structures': 2.3.0(typescript@5.9.2) - '@solana/codecs-numbers': 2.3.0(typescript@5.9.2) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/codecs-core': 2.3.0(typescript@5.8.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.8.3) + '@solana/codecs-numbers': 2.3.0(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) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/programs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/programs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/promises@2.3.0(typescript@5.9.2)': + '@solana/promises@2.3.0(typescript@5.8.3)': dependencies: - typescript: 5.9.2 + typescript: 5.8.3 - '@solana/rpc-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': - dependencies: - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-parsed-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec': 2.3.0(typescript@5.9.2) - '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@solana/rpc-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 2.3.0(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/rpc-parsed-types': 2.3.0(typescript@5.8.3) + '@solana/rpc-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/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 - '@solana/rpc-parsed-types@2.3.0(typescript@5.9.2)': + '@solana/rpc-parsed-types@2.3.0(typescript@5.8.3)': dependencies: - typescript: 5.9.2 + typescript: 5.8.3 - '@solana/rpc-spec-types@2.3.0(typescript@5.9.2)': + '@solana/rpc-spec-types@2.3.0(typescript@5.8.3)': dependencies: - typescript: 5.9.2 + typescript: 5.8.3 - '@solana/rpc-spec@2.3.0(typescript@5.9.2)': + '@solana/rpc-spec@2.3.0(typescript@5.8.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/errors': 2.3.0(typescript@5.8.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 - '@solana/rpc-subscriptions-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/rpc-subscriptions-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.2) - '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@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/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 - '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@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.9.2) - '@solana/functional': 2.3.0(typescript@5.9.2) - '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.2) - '@solana/subscribable': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@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) + '@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: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/functional': 2.3.0(typescript@5.9.2) - '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.2) - '@solana/subscribable': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) - - '@solana/rpc-subscriptions-spec@2.3.0(typescript@5.9.2)': - dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/promises': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) - '@solana/subscribable': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 - - '@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/fast-stable-stringify': 2.3.0(typescript@5.9.2) - '@solana/functional': 2.3.0(typescript@5.9.2) - '@solana/promises': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-subscriptions-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-subscriptions-channel-websocket': 2.3.0(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.2) - '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/subscribable': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.8.3)(ws@8.18.2(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: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + '@solana/rpc-subscriptions-spec@2.3.0(typescript@5.8.3)': + dependencies: + '@solana/errors': 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/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.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/fast-stable-stringify': 2.3.0(typescript@5.9.2) - '@solana/functional': 2.3.0(typescript@5.9.2) - '@solana/promises': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-subscriptions-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-subscriptions-channel-websocket': 2.3.0(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.2) - '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/subscribable': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@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) + '@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@8.18.0(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.2(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@8.18.2(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-transformers@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/rpc-transformers@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/functional': 2.3.0(typescript@5.9.2) - '@solana/nominal-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@solana/errors': 2.3.0(typescript@5.8.3) + '@solana/functional': 2.3.0(typescript@5.8.3) + '@solana/nominal-types': 2.3.0(typescript@5.8.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.8.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/rpc-transport-http@2.3.0(typescript@5.9.2)': + '@solana/rpc-transport-http@2.3.0(typescript@5.8.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 - undici-types: 7.15.0 + '@solana/errors': 2.3.0(typescript@5.8.3) + '@solana/rpc-spec': 2.3.0(typescript@5.8.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 + undici-types: 7.16.0 - '@solana/rpc-types@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/rpc-types@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/codecs-numbers': 2.3.0(typescript@5.9.2) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/nominal-types': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 2.3.0(typescript@5.8.3) + '@solana/codecs-numbers': 2.3.0(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/nominal-types': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/rpc@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': - dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/fast-stable-stringify': 2.3.0(typescript@5.9.2) - '@solana/functional': 2.3.0(typescript@5.9.2) - '@solana/rpc-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-spec': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-transport-http': 2.3.0(typescript@5.9.2) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@solana/rpc@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + 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/rpc-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-spec': 2.3.0(typescript@5.8.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.8.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-transport-http': 2.3.0(typescript@5.8.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/signers@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/signers@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/instructions': 2.3.0(typescript@5.9.2) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/nominal-types': 2.3.0(typescript@5.9.2) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 2.3.0(typescript@5.8.3) + '@solana/errors': 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/nominal-types': 2.3.0(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 - '@solana/spl-token-group@0.0.7(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/spl-token-group@0.0.7(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript - '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript - '@solana/spl-token@0.4.14(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@solana/spl-token-group': 0.0.7(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@solana/spl-token-group': 0.0.7(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -8355,95 +8305,112 @@ snapshots: - typescript - utf-8-validate - '@solana/subscribable@2.3.0(typescript@5.9.2)': + '@solana/subscribable@2.3.0(typescript@5.8.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/errors': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 - '@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@solana/accounts': 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/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(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.9.2) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/promises': 2.3.0(typescript@5.9.2) - '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@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.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/promises': 2.3.0(typescript@5.9.2) - '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@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) + '@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@8.18.0(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-messages@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': - dependencies: - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/codecs-data-structures': 2.3.0(typescript@5.9.2) - '@solana/codecs-numbers': 2.3.0(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/functional': 2.3.0(typescript@5.9.2) - '@solana/instructions': 2.3.0(typescript@5.9.2) - '@solana/nominal-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.2(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@8.18.2(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/transactions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': - dependencies: - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs-core': 2.3.0(typescript@5.9.2) - '@solana/codecs-data-structures': 2.3.0(typescript@5.9.2) - '@solana/codecs-numbers': 2.3.0(typescript@5.9.2) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/functional': 2.3.0(typescript@5.9.2) - '@solana/instructions': 2.3.0(typescript@5.9.2) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/nominal-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 + '@solana/transaction-messages@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 2.3.0(typescript@5.8.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.8.3) + '@solana/codecs-numbers': 2.3.0(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/nominal-types': 2.3.0(typescript@5.8.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@solana/transactions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 2.3.0(typescript@5.8.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.8.3) + '@solana/codecs-numbers': 2.3.0(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/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/nominal-types': 2.3.0(typescript@5.8.3) + '@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) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.28.3 - '@noble/curves': 1.9.7 + '@babel/runtime': 7.27.6 + '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 - '@solana/codecs-numbers': 2.3.0(typescript@5.9.2) + '@solana/codecs-numbers': 2.1.1(typescript@5.8.3) agentkeepalive: 4.6.0 bn.js: 5.2.2 borsh: 0.7.0 @@ -8452,7 +8419,7 @@ snapshots: fast-stable-stringify: 1.0.0 jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) node-fetch: 2.7.0 - rpc-websockets: 9.1.3 + rpc-websockets: 9.1.1 superstruct: 2.0.2 transitivePeerDependencies: - bufferutil @@ -8460,56 +8427,56 @@ snapshots: - typescript - utf-8-validate - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.3)': + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 - '@svgr/babel-preset@8.1.0(@babel/core@7.28.3)': + '@svgr/babel-preset@8.1.0(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.28.3 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.28.3) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.3) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.27.4) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.27.4) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.27.4) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.27.4) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.27.4) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.27.4) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.27.4) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.27.4) - '@svgr/core@8.1.0(typescript@5.9.2)': + '@svgr/core@8.1.0(typescript@5.8.3)': dependencies: - '@babel/core': 7.28.3 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@svgr/babel-preset': 8.1.0(@babel/core@7.27.4) camelcase: 6.3.0 - cosmiconfig: 8.3.6(typescript@5.9.2) + cosmiconfig: 8.3.6(typescript@5.8.3) snake-case: 3.0.4 transitivePeerDependencies: - supports-color @@ -8517,42 +8484,44 @@ snapshots: '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.27.6 entities: 4.5.0 - '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.2))': + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.8.3))': dependencies: - '@babel/core': 7.28.3 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.3) - '@svgr/core': 8.1.0(typescript@5.9.2) + '@babel/core': 7.27.4 + '@svgr/babel-preset': 8.1.0(@babel/core@7.27.4) + '@svgr/core': 8.1.0(typescript@5.8.3) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 transitivePeerDependencies: - supports-color - '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.9.2))(typescript@5.9.2)': + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.8.3))(typescript@5.8.3)': dependencies: - '@svgr/core': 8.1.0(typescript@5.9.2) - cosmiconfig: 8.3.6(typescript@5.9.2) + '@svgr/core': 8.1.0(typescript@5.8.3) + cosmiconfig: 8.3.6(typescript@5.8.3) deepmerge: 4.3.1 svgo: 3.3.2 transitivePeerDependencies: - typescript - '@svgr/webpack@8.1.0(typescript@5.9.2)': + '@svgr/webpack@8.1.0(typescript@5.8.3)': dependencies: - '@babel/core': 7.28.3 - '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.3) - '@babel/preset-env': 7.28.3(@babel/core@7.28.3) - '@babel/preset-react': 7.27.1(@babel/core@7.28.3) - '@babel/preset-typescript': 7.27.1(@babel/core@7.28.3) - '@svgr/core': 8.1.0(typescript@5.9.2) - '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2)) - '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2))(typescript@5.9.2) + '@babel/core': 7.27.4 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.27.4) + '@babel/preset-env': 7.27.2(@babel/core@7.27.4) + '@babel/preset-react': 7.27.1(@babel/core@7.27.4) + '@babel/preset-typescript': 7.27.1(@babel/core@7.27.4) + '@svgr/core': 8.1.0(typescript@5.8.3) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.8.3)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.8.3))(typescript@5.8.3) transitivePeerDependencies: - supports-color - typescript + '@swc/counter@0.1.3': {} + '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -8561,16 +8530,16 @@ snapshots: dependencies: tslib: 2.8.1 - '@tanstack/query-core@5.85.9': {} + '@tanstack/query-core@5.81.2': {} - '@tanstack/react-query@5.85.9(react@19.1.1)': + '@tanstack/react-query@5.81.2(react@19.1.0)': dependencies: - '@tanstack/query-core': 5.85.9 - react: 19.1.1 + '@tanstack/query-core': 5.81.2 + react: 19.1.0 '@trysound/sax@0.2.0': {} - '@tybys/wasm-util@0.10.0': + '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.8.1 optional: true @@ -8578,7 +8547,7 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.18.0 + '@types/node': 22.15.33 '@types/chai@5.2.2': dependencies: @@ -8586,7 +8555,7 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 22.18.0 + '@types/node': 22.15.33 '@types/debug@4.1.12': dependencies: @@ -8596,9 +8565,9 @@ snapshots: '@types/estree@1.0.8': {} - '@types/express-serve-static-core@5.0.7': + '@types/express-serve-static-core@5.0.6': dependencies: - '@types/node': 22.18.0 + '@types/node': 22.15.33 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 0.17.5 @@ -8606,7 +8575,7 @@ snapshots: '@types/express@5.0.3': dependencies: '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 5.0.7 + '@types/express-serve-static-core': 5.0.6 '@types/serve-static': 1.15.8 '@types/http-errors@2.0.5': {} @@ -8615,19 +8584,17 @@ snapshots: '@types/json5@0.0.29': {} - '@types/lodash@4.17.20': {} - '@types/mime@1.3.5': {} '@types/ms@2.1.0': {} '@types/node@12.20.55': {} - '@types/node@20.19.12': + '@types/node@20.19.1': dependencies: undici-types: 6.21.0 - '@types/node@22.18.0': + '@types/node@22.15.33': dependencies: undici-types: 6.21.0 @@ -8635,23 +8602,23 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react-dom@19.1.9(@types/react@19.1.12)': + '@types/react-dom@19.1.6(@types/react@19.1.8)': dependencies: - '@types/react': 19.1.12 + '@types/react': 19.1.8 - '@types/react@19.1.12': + '@types/react@19.1.8': dependencies: csstype: 3.1.3 '@types/send@0.17.5': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.18.0 + '@types/node': 22.15.33 '@types/serve-static@1.15.8': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.18.0 + '@types/node': 22.15.33 '@types/send': 0.17.5 '@types/trusted-types@2.0.7': {} @@ -8660,162 +8627,161 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 22.18.0 + '@types/node': 22.15.33 '@types/ws@8.18.1': dependencies: - '@types/node': 22.18.0 + '@types/node': 22.15.33 - '@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.42.0 - '@typescript-eslint/type-utils': 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/utils': 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.42.0 - eslint: 9.34.0(jiti@1.21.7) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.35.0 + '@typescript-eslint/type-utils': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.35.0 + eslint: 9.29.0(jiti@1.21.7) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.42.0 - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.42.0 + '@typescript-eslint/scope-manager': 8.35.0 + '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.35.0 debug: 4.4.1 - eslint: 9.34.0(jiti@1.21.7) - typescript: 5.9.2 + eslint: 9.29.0(jiti@1.21.7) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.42.0(typescript@5.9.2)': + '@typescript-eslint/project-service@8.35.0(typescript@5.8.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.2) - '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/tsconfig-utils': 8.35.0(typescript@5.8.3) + '@typescript-eslint/types': 8.35.0 debug: 4.4.1 - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.42.0': + '@typescript-eslint/scope-manager@8.35.0': dependencies: - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/visitor-keys': 8.42.0 + '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/visitor-keys': 8.35.0 - '@typescript-eslint/tsconfig-utils@8.42.0(typescript@5.9.2)': + '@typescript-eslint/tsconfig-utils@8.35.0(typescript@5.8.3)': dependencies: - typescript: 5.9.2 + typescript: 5.8.3 - '@typescript-eslint/type-utils@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) debug: 4.4.1 - eslint: 9.34.0(jiti@1.21.7) - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 + eslint: 9.29.0(jiti@1.21.7) + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.42.0': {} + '@typescript-eslint/types@8.35.0': {} - '@typescript-eslint/typescript-estree@8.42.0(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.35.0(typescript@5.8.3)': dependencies: - '@typescript-eslint/project-service': 8.42.0(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.2) - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/visitor-keys': 8.42.0 + '@typescript-eslint/project-service': 8.35.0(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.35.0(typescript@5.8.3) + '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/visitor-keys': 8.35.0 debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.8.0(eslint@9.34.0(jiti@1.21.7)) - '@typescript-eslint/scope-manager': 8.42.0 - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) - eslint: 9.34.0(jiti@1.21.7) - typescript: 5.9.2 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.35.0 + '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) + eslint: 9.29.0(jiti@1.21.7) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.42.0': + '@typescript-eslint/visitor-keys@8.35.0': dependencies: - '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/types': 8.35.0 eslint-visitor-keys: 4.2.1 - '@unrs/resolver-binding-android-arm-eabi@1.11.1': + '@unrs/resolver-binding-android-arm-eabi@1.9.2': optional: true - '@unrs/resolver-binding-android-arm64@1.11.1': + '@unrs/resolver-binding-android-arm64@1.9.2': optional: true - '@unrs/resolver-binding-darwin-arm64@1.11.1': + '@unrs/resolver-binding-darwin-arm64@1.9.2': optional: true - '@unrs/resolver-binding-darwin-x64@1.11.1': + '@unrs/resolver-binding-darwin-x64@1.9.2': optional: true - '@unrs/resolver-binding-freebsd-x64@1.11.1': + '@unrs/resolver-binding-freebsd-x64@1.9.2': optional: true - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + '@unrs/resolver-binding-linux-arm-gnueabihf@1.9.2': optional: true - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + '@unrs/resolver-binding-linux-arm-musleabihf@1.9.2': optional: true - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + '@unrs/resolver-binding-linux-arm64-gnu@1.9.2': optional: true - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + '@unrs/resolver-binding-linux-arm64-musl@1.9.2': optional: true - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + '@unrs/resolver-binding-linux-ppc64-gnu@1.9.2': optional: true - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + '@unrs/resolver-binding-linux-riscv64-gnu@1.9.2': optional: true - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + '@unrs/resolver-binding-linux-riscv64-musl@1.9.2': optional: true - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + '@unrs/resolver-binding-linux-s390x-gnu@1.9.2': optional: true - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + '@unrs/resolver-binding-linux-x64-gnu@1.9.2': optional: true - '@unrs/resolver-binding-linux-x64-musl@1.11.1': + '@unrs/resolver-binding-linux-x64-musl@1.9.2': optional: true - '@unrs/resolver-binding-wasm32-wasi@1.11.1': + '@unrs/resolver-binding-wasm32-wasi@1.9.2': dependencies: - '@napi-rs/wasm-runtime': 0.2.12 + '@napi-rs/wasm-runtime': 0.2.11 optional: true - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + '@unrs/resolver-binding-win32-arm64-msvc@1.9.2': optional: true - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + '@unrs/resolver-binding-win32-ia32-msvc@1.9.2': optional: true - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + '@unrs/resolver-binding-win32-x64-msvc@1.9.2': optional: true '@vercel/functions@2.2.13': @@ -8832,16 +8798,16 @@ snapshots: '@types/chai': 5.2.2 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.3.3 + chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.18 + magic-string: 0.30.17 optionalDependencies: - vite: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite: 6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) '@vitest/pretty-format@3.2.4': dependencies: @@ -8856,7 +8822,7 @@ snapshots: '@vitest/snapshot@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.18 + magic-string: 0.30.17 pathe: 2.0.3 '@vitest/spy@3.2.4': @@ -8866,23 +8832,21 @@ snapshots: '@vitest/utils@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - loupe: 3.2.1 + loupe: 3.1.4 tinyrainbow: 2.0.0 - '@wagmi/connectors@5.9.9(@types/react@19.1.12)(@vercel/functions@2.2.13)(@wagmi/core@2.20.3(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': + '@wagmi/connectors@5.8.5(@types/react@19.1.8)(@wagmi/core@2.17.3(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)))(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67))(zod@3.25.67)': dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.12)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.12)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@gemini-wallet/core': 0.2.0(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@coinbase/wallet-sdk': 4.3.3 '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.20.3(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@wagmi/core': 2.17.3(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8898,51 +8862,48 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil - db0 - encoding - - immer - ioredis - react - supports-color - uploadthing - - use-sync-external-store - utf-8-validate - zod - '@wagmi/core@2.20.3(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@wagmi/core@2.17.3(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67))': dependencies: eventemitter3: 5.0.1 - mipd: 0.0.7(typescript@5.9.2) - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.0(@types/react@19.1.12)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + mipd: 0.0.7(typescript@5.8.3) + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + zustand: 5.0.0(@types/react@19.1.8)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)) optionalDependencies: - '@tanstack/query-core': 5.85.9 - typescript: 5.9.2 + '@tanstack/query-core': 5.81.2 + typescript: 5.8.3 transitivePeerDependencies: - '@types/react' - immer - react - use-sync-external-store - '@walletconnect/core@2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/core@2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': 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.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@vercel/functions@2.2.13) + '@walletconnect/keyvaluestorage': 1.1.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.0(@vercel/functions@2.2.13) - '@walletconnect/utils': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0 + '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 @@ -8961,7 +8922,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -8972,21 +8932,21 @@ snapshots: - utf-8-validate - zod - '@walletconnect/core@2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/core@2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': 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.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@vercel/functions@2.2.13) + '@walletconnect/keyvaluestorage': 1.1.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.1(@vercel/functions@2.2.13) - '@walletconnect/utils': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1 + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 @@ -9005,7 +8965,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9020,18 +8979,18 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: - '@reown/appkit': 1.7.8(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit': 1.7.8(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) '@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(@vercel/functions@2.2.13) - '@walletconnect/sign-client': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@vercel/functions@2.2.13) - '@walletconnect/universal-provider': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/utils': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@walletconnect/types': 2.21.1 + '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -9048,7 +9007,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9108,11 +9066,11 @@ snapshots: - bufferutil - utf-8-validate - '@walletconnect/keyvaluestorage@1.1.1(@vercel/functions@2.2.13)': + '@walletconnect/keyvaluestorage@1.1.1': dependencies: '@walletconnect/safe-json': 1.0.2 idb-keyval: 6.2.2 - unstorage: 1.17.0(@vercel/functions@2.2.13)(idb-keyval@6.2.2) + unstorage: 1.16.0(idb-keyval@6.2.2) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -9126,7 +9084,6 @@ snapshots: - '@planetscale/database' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 @@ -9154,16 +9111,16 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/sign-client@2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/sign-client@2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: - '@walletconnect/core': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/core': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) '@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.0(@vercel/functions@2.2.13) - '@walletconnect/utils': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0 + '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -9179,7 +9136,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9190,16 +9146,16 @@ snapshots: - utf-8-validate - zod - '@walletconnect/sign-client@2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/sign-client@2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: - '@walletconnect/core': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/core': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) '@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.1(@vercel/functions@2.2.13) - '@walletconnect/utils': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1 + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -9215,7 +9171,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9230,12 +9185,12 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/types@2.21.0(@vercel/functions@2.2.13)': + '@walletconnect/types@2.21.0': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/keyvaluestorage': 1.1.1(@vercel/functions@2.2.13) + '@walletconnect/keyvaluestorage': 1.1.1 '@walletconnect/logger': 2.1.2 events: 3.3.0 transitivePeerDependencies: @@ -9252,19 +9207,18 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 - ioredis - uploadthing - '@walletconnect/types@2.21.1(@vercel/functions@2.2.13)': + '@walletconnect/types@2.21.1': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/keyvaluestorage': 1.1.1(@vercel/functions@2.2.13) + '@walletconnect/keyvaluestorage': 1.1.1 '@walletconnect/logger': 2.1.2 events: 3.3.0 transitivePeerDependencies: @@ -9281,25 +9235,24 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 - ioredis - uploadthing - '@walletconnect/universal-provider@2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/universal-provider@2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': 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(@vercel/functions@2.2.13) + '@walletconnect/keyvaluestorage': 1.1.1 '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.0(@vercel/functions@2.2.13) - '@walletconnect/utils': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/sign-client': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@walletconnect/types': 2.21.0 + '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -9316,7 +9269,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9328,18 +9280,18 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/universal-provider@2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': 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(@vercel/functions@2.2.13) + '@walletconnect/keyvaluestorage': 1.1.1 '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@vercel/functions@2.2.13) - '@walletconnect/utils': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + '@walletconnect/types': 2.21.1 + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -9356,7 +9308,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9368,25 +9319,25 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/utils@2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@vercel/functions@2.2.13) + '@walletconnect/keyvaluestorage': 1.1.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.0(@vercel/functions@2.2.13) + '@walletconnect/types': 2.21.0 '@walletconnect/window-getters': 1.0.1 '@walletconnect/window-metadata': 1.0.1 bs58: 6.0.0 detect-browser: 5.3.0 query-string: 7.1.3 uint8arrays: 3.1.0 - viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -9401,7 +9352,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9412,25 +9362,25 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/utils@2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@vercel/functions@2.2.13) + '@walletconnect/keyvaluestorage': 1.1.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.1(@vercel/functions@2.2.13) + '@walletconnect/types': 2.21.1 '@walletconnect/window-getters': 1.0.1 '@walletconnect/window-metadata': 1.0.1 bs58: 6.0.0 detect-browser: 5.3.0 query-string: 7.1.3 uint8arrays: 3.1.0 - viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -9445,7 +9395,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9465,25 +9414,20 @@ snapshots: '@walletconnect/window-getters': 1.0.1 tslib: 1.14.1 - abitype@1.0.6(typescript@5.9.2)(zod@3.25.76): - optionalDependencies: - typescript: 5.9.2 - zod: 3.25.76 - - abitype@1.0.8(typescript@5.9.2)(zod@3.25.76): + abitype@1.0.6(typescript@5.8.3)(zod@3.25.67): optionalDependencies: - typescript: 5.9.2 - zod: 3.25.76 + typescript: 5.8.3 + zod: 3.25.67 - abitype@1.1.0(typescript@5.9.2)(zod@3.22.4): + abitype@1.0.8(typescript@5.8.3)(zod@3.22.4): optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 zod: 3.22.4 - abitype@1.1.0(typescript@5.9.2)(zod@3.25.76): + abitype@1.0.8(typescript@5.8.3)(zod@3.25.67): optionalDependencies: - typescript: 5.9.2 - zod: 3.25.76 + typescript: 5.8.3 + zod: 3.25.67 accepts@1.3.8: dependencies: @@ -9496,7 +9440,7 @@ snapshots: acorn@8.15.0: {} - agent-base@7.1.4: {} + agent-base@7.1.3: {} agentkeepalive@4.6.0: dependencies: @@ -9511,7 +9455,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.2.0: {} + ansi-regex@6.1.0: {} ansi-styles@4.3.0: dependencies: @@ -9623,14 +9567,22 @@ snapshots: axe-core@4.10.3: {} - axios-retry@4.5.0(axios@1.11.0): + axios-retry@4.5.0(axios@1.12.2): dependencies: - axios: 1.11.0 + axios: 1.12.2 is-retry-allowed: 2.2.0 - axios@1.11.0: + axios@1.10.0: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.3 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axios@1.12.2: dependencies: - follow-redirects: 1.15.11 + follow-redirects: 1.15.9 form-data: 4.0.4 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -9638,27 +9590,27 @@ snapshots: axobject-query@4.1.0: {} - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.3): + babel-plugin-polyfill-corejs2@0.4.13(@babel/core@7.27.4): dependencies: - '@babel/compat-data': 7.28.0 - '@babel/core': 7.28.3 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) + '@babel/compat-data': 7.27.5 + '@babel/core': 7.27.4 + '@babel/helper-define-polyfill-provider': 0.6.4(@babel/core@7.27.4) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.3): + babel-plugin-polyfill-corejs3@0.11.1(@babel/core@7.27.4): dependencies: - '@babel/core': 7.28.3 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) - core-js-compat: 3.45.1 + '@babel/core': 7.27.4 + '@babel/helper-define-polyfill-provider': 0.6.4(@babel/core@7.27.4) + core-js-compat: 3.43.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.3): + babel-plugin-polyfill-regenerator@0.6.4(@babel/core@7.27.4): dependencies: - '@babel/core': 7.28.3 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) + '@babel/core': 7.27.4 + '@babel/helper-define-polyfill-provider': 0.6.4(@babel/core@7.27.4) transitivePeerDependencies: - supports-color @@ -9678,7 +9630,7 @@ snapshots: dependencies: bindings: 1.5.0 - bignumber.js@9.3.1: {} + bignumber.js@9.3.0: {} binary-extensions@2.3.0: {} @@ -9713,7 +9665,7 @@ snapshots: bs58: 4.0.1 text-encoding-utf-8: 1.0.2 - bowser@2.12.1: {} + bowser@2.11.0: {} brace-expansion@1.1.12: dependencies: @@ -9728,12 +9680,12 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.25.4: + browserslist@4.25.0: dependencies: - caniuse-lite: 1.0.30001739 - electron-to-chromium: 1.5.214 + caniuse-lite: 1.0.30001724 + electron-to-chromium: 1.5.173 node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.4) + update-browserslist-db: 1.1.3(browserslist@4.25.0) bs58@4.0.1: dependencies: @@ -9752,11 +9704,15 @@ snapshots: dependencies: node-gyp-build: 4.8.4 - bundle-require@5.1.0(esbuild@0.25.9): + bundle-require@5.1.0(esbuild@0.25.5): dependencies: - esbuild: 0.25.9 + esbuild: 0.25.5 load-tsconfig: 0.2.5 + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + bytes@3.1.2: {} cac@6.7.14: {} @@ -9786,22 +9742,22 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001739: {} + caniuse-lite@1.0.30001724: {} - chai@5.3.3: + chai@5.2.0: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.2.1 - pathval: 2.0.1 + loupe: 3.1.4 + pathval: 2.0.0 chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.6.0: {} + chalk@5.4.1: {} charenc@0.0.2: {} @@ -9861,7 +9817,9 @@ snapshots: commander@12.1.0: {} - commander@14.0.0: {} + commander@13.1.0: {} + + commander@14.0.1: {} commander@2.20.3: {} @@ -9891,20 +9849,20 @@ snapshots: cookie@0.7.1: {} - core-js-compat@3.45.1: + core-js-compat@3.43.0: dependencies: - browserslist: 4.25.4 + browserslist: 4.25.0 core-util-is@1.0.3: {} - cosmiconfig@8.3.6(typescript@5.9.2): + cosmiconfig@8.3.6(typescript@5.8.3): dependencies: import-fresh: 3.3.1 js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 crc-32@1.2.2: {} @@ -9932,10 +9890,10 @@ snapshots: crypt@0.0.2: {} - css-select@5.2.2: + css-select@5.1.0: dependencies: boolbase: 1.0.0 - css-what: 6.2.2 + css-what: 6.1.0 domhandler: 5.0.3 domutils: 3.2.2 nth-check: 2.1.1 @@ -9950,7 +9908,7 @@ snapshots: mdn-data: 2.0.30 source-map-js: 1.2.1 - css-what@6.2.2: {} + css-what@6.1.0: {} cssesc@3.0.0: {} @@ -9958,7 +9916,7 @@ snapshots: dependencies: css-tree: 2.2.1 - cssstyle@4.6.0: + cssstyle@4.5.0: dependencies: '@asamuzakjp/css-color': 3.2.0 rrweb-cssom: 0.8.0 @@ -9992,7 +9950,7 @@ snapshots: date-fns@2.30.0: dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.27.6 dayjs@1.11.13: {} @@ -10014,7 +9972,7 @@ snapshots: decamelize@1.2.0: {} - decimal.js@10.6.0: {} + decimal.js@10.5.0: {} decode-uri-component@0.2.2: {} @@ -10044,9 +10002,9 @@ snapshots: depd@2.0.0: {} - derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.1.12)(react@19.1.1)): + derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.1.8)(react@19.1.0)): dependencies: - valtio: 1.13.2(@types/react@19.1.12)(react@19.1.1) + valtio: 1.13.2(@types/react@19.1.8)(react@19.1.0) destr@2.0.5: {} @@ -10107,14 +10065,14 @@ snapshots: eciesjs@0.4.15: dependencies: - '@ecies/ciphers': 0.2.4(@noble/ciphers@1.3.0) + '@ecies/ciphers': 0.2.3(@noble/ciphers@1.3.0) '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.7 + '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 ee-first@1.1.1: {} - electron-to-chromium@1.5.214: {} + electron-to-chromium@1.5.173: {} emoji-regex@8.0.0: {} @@ -10263,34 +10221,33 @@ snapshots: dependencies: es6-promise: 4.2.8 - esbuild@0.25.9: + esbuild@0.25.5: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.9 - '@esbuild/android-arm': 0.25.9 - '@esbuild/android-arm64': 0.25.9 - '@esbuild/android-x64': 0.25.9 - '@esbuild/darwin-arm64': 0.25.9 - '@esbuild/darwin-x64': 0.25.9 - '@esbuild/freebsd-arm64': 0.25.9 - '@esbuild/freebsd-x64': 0.25.9 - '@esbuild/linux-arm': 0.25.9 - '@esbuild/linux-arm64': 0.25.9 - '@esbuild/linux-ia32': 0.25.9 - '@esbuild/linux-loong64': 0.25.9 - '@esbuild/linux-mips64el': 0.25.9 - '@esbuild/linux-ppc64': 0.25.9 - '@esbuild/linux-riscv64': 0.25.9 - '@esbuild/linux-s390x': 0.25.9 - '@esbuild/linux-x64': 0.25.9 - '@esbuild/netbsd-arm64': 0.25.9 - '@esbuild/netbsd-x64': 0.25.9 - '@esbuild/openbsd-arm64': 0.25.9 - '@esbuild/openbsd-x64': 0.25.9 - '@esbuild/openharmony-arm64': 0.25.9 - '@esbuild/sunos-x64': 0.25.9 - '@esbuild/win32-arm64': 0.25.9 - '@esbuild/win32-ia32': 0.25.9 - '@esbuild/win32-x64': 0.25.9 + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 escalade@3.2.0: {} @@ -10298,21 +10255,21 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-next@15.1.7(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2): + eslint-config-next@15.1.7(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3): dependencies: '@next/eslint-plugin-next': 15.1.7 - '@rushstack/eslint-patch': 1.12.0 - '@typescript-eslint/eslint-plugin': 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/parser': 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) - eslint: 9.34.0(jiti@1.21.7) + '@rushstack/eslint-patch': 1.11.0 + '@typescript-eslint/eslint-plugin': 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) + eslint: 9.29.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.34.0(jiti@1.21.7)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.34.0(jiti@1.21.7)) - eslint-plugin-react: 7.37.5(eslint@9.34.0(jiti@1.21.7)) - eslint-plugin-react-hooks: 5.2.0(eslint@9.34.0(jiti@1.21.7)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.29.0(jiti@1.21.7)) + eslint-plugin-react: 7.37.5(eslint@9.29.0(jiti@1.21.7)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.29.0(jiti@1.21.7)) optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - eslint-import-resolver-webpack - eslint-plugin-import-x @@ -10326,33 +10283,33 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.34.0(jiti@1.21.7)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@1.21.7)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.1 - eslint: 9.34.0(jiti@1.21.7) + eslint: 9.29.0(jiti@1.21.7) get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 tinyglobby: 0.2.14 - unrs-resolver: 1.11.1 + unrs-resolver: 1.9.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) - eslint: 9.34.0(jiti@1.21.7) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) + eslint: 9.29.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.34.0(jiti@1.21.7)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -10361,9 +10318,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.34.0(jiti@1.21.7) + eslint: 9.29.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@1.21.7)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@1.21.7)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -10375,20 +10332,20 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsdoc@50.8.0(eslint@9.34.0(jiti@1.21.7)): + eslint-plugin-jsdoc@50.8.0(eslint@9.29.0(jiti@1.21.7)): dependencies: '@es-joy/jsdoccomment': 0.50.2 are-docs-informative: 0.0.2 comment-parser: 1.4.1 debug: 4.4.1 escape-string-regexp: 4.0.0 - eslint: 9.34.0(jiti@1.21.7) + eslint: 9.29.0(jiti@1.21.7) espree: 10.4.0 esquery: 1.6.0 parse-imports-exports: 0.2.4 @@ -10397,7 +10354,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@9.34.0(jiti@1.21.7)): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.29.0(jiti@1.21.7)): dependencies: aria-query: 5.3.2 array-includes: 3.1.9 @@ -10407,7 +10364,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.34.0(jiti@1.21.7) + eslint: 9.29.0(jiti@1.21.7) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -10416,18 +10373,18 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.5.4(eslint@9.34.0(jiti@1.21.7))(prettier@3.5.2): + eslint-plugin-prettier@5.5.0(eslint@9.29.0(jiti@1.21.7))(prettier@3.5.2): dependencies: - eslint: 9.34.0(jiti@1.21.7) + eslint: 9.29.0(jiti@1.21.7) prettier: 3.5.2 prettier-linter-helpers: 1.0.0 - synckit: 0.11.11 + synckit: 0.11.8 - eslint-plugin-react-hooks@5.2.0(eslint@9.34.0(jiti@1.21.7)): + eslint-plugin-react-hooks@5.2.0(eslint@9.29.0(jiti@1.21.7)): dependencies: - eslint: 9.34.0(jiti@1.21.7) + eslint: 9.29.0(jiti@1.21.7) - eslint-plugin-react@7.37.5(eslint@9.34.0(jiti@1.21.7)): + eslint-plugin-react@7.37.5(eslint@9.29.0(jiti@1.21.7)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -10435,7 +10392,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 9.34.0(jiti@1.21.7) + eslint: 9.29.0(jiti@1.21.7) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -10458,17 +10415,17 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.34.0(jiti@1.21.7): + eslint@9.29.0(jiti@1.21.7): dependencies: - '@eslint-community/eslint-utils': 4.8.0(eslint@9.34.0(jiti@1.21.7)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@1.21.7)) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.3.1 - '@eslint/core': 0.15.2 + '@eslint/config-array': 0.20.1 + '@eslint/config-helpers': 0.2.3 + '@eslint/core': 0.14.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.34.0 - '@eslint/plugin-kit': 0.3.5 - '@humanfs/node': 0.16.7 + '@eslint/js': 9.29.0 + '@eslint/plugin-kit': 0.3.2 + '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 @@ -10564,7 +10521,7 @@ snapshots: events@3.3.0: {} - expect-type@1.2.2: {} + expect-type@1.2.1: {} express@4.21.2: dependencies: @@ -10645,9 +10602,9 @@ snapshots: dependencies: reusify: 1.1.0 - fdir@6.5.0(picomatch@4.0.3): + fdir@6.4.6(picomatch@4.0.2): optionalDependencies: - picomatch: 4.0.3 + picomatch: 4.0.2 file-entry-cache@8.0.0: dependencies: @@ -10685,9 +10642,9 @@ snapshots: fix-dts-default-cjs-exports@1.0.1: dependencies: - magic-string: 0.30.18 - mlly: 1.8.0 - rollup: 4.50.0 + magic-string: 0.30.17 + mlly: 1.7.4 + rollup: 4.44.0 flat-cache@4.0.1: dependencies: @@ -10696,7 +10653,7 @@ snapshots: flatted@3.3.3: {} - follow-redirects@1.15.11: {} + follow-redirects@1.15.9: {} for-each@0.3.5: dependencies: @@ -10707,6 +10664,14 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + form-data@4.0.3: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + form-data@4.0.4: dependencies: asynckit: 0.4.0 @@ -10784,6 +10749,8 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + globals@11.12.0: {} + globals@14.0.0: {} globalthis@1.0.4: @@ -10807,14 +10774,14 @@ snapshots: graphql@16.11.0: {} - h3@1.15.4: + h3@1.15.3: dependencies: cookie-es: 1.2.2 crossws: 0.3.5 defu: 6.1.4 destr: 2.0.5 iron-webcrypto: 1.2.1 - node-mock-http: 1.0.2 + node-mock-http: 1.0.0 radix3: 1.1.2 ufo: 1.6.1 uncrypto: 0.1.3 @@ -10841,7 +10808,7 @@ snapshots: dependencies: function-bind: 1.1.2 - hono@4.9.6: {} + hono@4.8.2: {} html-encoding-sniffer@4.0.0: dependencies: @@ -10857,14 +10824,14 @@ snapshots: http-proxy-agent@7.0.2: dependencies: - agent-base: 7.1.4 + agent-base: 7.1.3 debug: 4.4.1 transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6: dependencies: - agent-base: 7.1.4 + agent-base: 7.1.3 debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -10881,8 +10848,6 @@ snapshots: dependencies: safer-buffer: 2.1.2 - idb-keyval@6.2.1: {} - idb-keyval@6.2.2: {} ieee754@1.2.1: {} @@ -11059,9 +11024,9 @@ snapshots: dependencies: ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - isows@1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + isows@1.0.7(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) iterator.prototype@1.1.5: dependencies: @@ -11100,7 +11065,7 @@ snapshots: jose@5.10.0: {} - jose@6.1.0: {} + jose@6.0.11: {} joycon@3.1.1: {} @@ -11116,14 +11081,14 @@ snapshots: jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: - cssstyle: 4.6.0 + cssstyle: 4.5.0 data-urls: 5.0.0 - decimal.js: 10.6.0 + decimal.js: 10.5.0 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.21 + nwsapi: 2.2.20 parse5: 7.3.0 rrweb-cssom: 0.8.0 saxes: 6.0.0 @@ -11134,7 +11099,7 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil @@ -11202,21 +11167,21 @@ snapshots: lines-and-columns@1.2.4: {} - lit-element@4.2.1: + lit-element@4.2.0: dependencies: - '@lit-labs/ssr-dom-shim': 1.4.0 - '@lit/reactive-element': 2.1.1 - lit-html: 3.3.1 + '@lit-labs/ssr-dom-shim': 1.3.0 + '@lit/reactive-element': 2.1.0 + lit-html: 3.3.0 - lit-html@3.3.1: + lit-html@3.3.0: dependencies: '@types/trusted-types': 2.0.7 lit@3.3.0: dependencies: - '@lit/reactive-element': 2.1.1 - lit-element: 4.2.1 - lit-html: 3.3.1 + '@lit/reactive-element': 2.1.0 + lit-element: 4.2.0 + lit-html: 3.3.0 load-tsconfig@0.2.5: {} @@ -11240,7 +11205,7 @@ snapshots: dependencies: js-tokens: 4.0.0 - loupe@3.2.1: {} + loupe@3.1.4: {} lower-case@2.0.2: dependencies: @@ -11252,9 +11217,9 @@ snapshots: dependencies: yallist: 3.1.1 - magic-string@0.30.18: + magic-string@0.30.17: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.5.0 math-intrinsics@1.1.0: {} @@ -11303,11 +11268,11 @@ snapshots: minipass@7.1.2: {} - mipd@0.0.7(typescript@5.9.2): + mipd@0.0.7(typescript@5.8.3): optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 - mlly@1.8.0: + mlly@1.7.4: dependencies: acorn: 8.15.0 pathe: 2.0.3 @@ -11328,31 +11293,33 @@ snapshots: nanoid@3.3.11: {} - napi-postinstall@0.3.3: {} + napi-postinstall@0.2.4: {} natural-compare@1.4.0: {} negotiator@0.6.3: {} - next@15.5.2(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + next@15.3.4(@babel/core@7.27.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - '@next/env': 15.5.2 + '@next/env': 15.3.4 + '@swc/counter': 0.1.3 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001739 + busboy: 1.6.0 + caniuse-lite: 1.0.30001724 postcss: 8.4.31 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - styled-jsx: 5.1.6(@babel/core@7.28.3)(react@19.1.1) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + styled-jsx: 5.1.6(@babel/core@7.27.4)(react@19.1.0) optionalDependencies: - '@next/swc-darwin-arm64': 15.5.2 - '@next/swc-darwin-x64': 15.5.2 - '@next/swc-linux-arm64-gnu': 15.5.2 - '@next/swc-linux-arm64-musl': 15.5.2 - '@next/swc-linux-x64-gnu': 15.5.2 - '@next/swc-linux-x64-musl': 15.5.2 - '@next/swc-win32-arm64-msvc': 15.5.2 - '@next/swc-win32-x64-msvc': 15.5.2 - sharp: 0.34.3 + '@next/swc-darwin-arm64': 15.3.4 + '@next/swc-darwin-x64': 15.3.4 + '@next/swc-linux-arm64-gnu': 15.3.4 + '@next/swc-linux-arm64-musl': 15.3.4 + '@next/swc-linux-x64-gnu': 15.3.4 + '@next/swc-linux-x64-musl': 15.3.4 + '@next/swc-win32-arm64-msvc': 15.3.4 + '@next/swc-win32-x64-msvc': 15.3.4 + sharp: 0.34.2 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -11364,7 +11331,7 @@ snapshots: node-addon-api@2.0.2: {} - node-fetch-native@1.6.7: {} + node-fetch-native@1.6.6: {} node-fetch@2.7.0: dependencies: @@ -11372,7 +11339,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-mock-http@1.0.2: {} + node-mock-http@1.0.0: {} node-releases@2.0.19: {} @@ -11382,7 +11349,7 @@ snapshots: dependencies: boolbase: 1.0.0 - nwsapi@2.2.21: {} + nwsapi@2.2.20: {} obj-multiplex@1.0.0: dependencies: @@ -11437,7 +11404,7 @@ snapshots: ofetch@1.4.1: dependencies: destr: 2.0.5 - node-fetch-native: 1.6.7 + node-fetch-native: 1.6.6 ufo: 1.6.1 on-exit-leak-free@0.2.0: {} @@ -11465,75 +11432,61 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - ox@0.4.4(typescript@5.9.2)(zod@3.25.76): + ox@0.4.4(typescript@5.8.3)(zod@3.25.67): dependencies: '@adraffy/ens-normalize': 1.11.0 - '@noble/curves': 1.9.7 + '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.2)(zod@3.25.76) + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.67) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - zod - ox@0.6.7(typescript@5.9.2)(zod@3.25.76): + ox@0.6.7(typescript@5.8.3)(zod@3.25.67): dependencies: '@adraffy/ens-normalize': 1.11.0 '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@scure/bip32': 1.6.2 '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.9.2)(zod@3.25.76) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - zod - - ox@0.6.9(typescript@5.9.2)(zod@3.25.76): - dependencies: - '@adraffy/ens-normalize': 1.11.0 - '@noble/curves': 1.9.7 - '@noble/hashes': 1.8.0 - '@scure/bip32': 1.7.0 - '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.2)(zod@3.25.76) + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.67) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - zod - ox@0.9.3(typescript@5.9.2)(zod@3.22.4): + ox@0.8.1(typescript@5.8.3)(zod@3.22.4): dependencies: '@adraffy/ens-normalize': 1.11.0 '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.2)(zod@3.22.4) + abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - zod - ox@0.9.3(typescript@5.9.2)(zod@3.25.76): + ox@0.8.1(typescript@5.8.3)(zod@3.25.67): dependencies: '@adraffy/ens-normalize': 1.11.0 '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.2)(zod@3.25.76) + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.67) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - zod @@ -11597,13 +11550,13 @@ snapshots: pathe@2.0.3: {} - pathval@2.0.1: {} + pathval@2.0.0: {} picocolors@1.1.1: {} picomatch@2.3.1: {} - picomatch@4.0.3: {} + picomatch@4.0.2: {} pify@2.3.0: {} @@ -11637,7 +11590,7 @@ snapshots: pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.8.0 + mlly: 1.7.4 pathe: 2.0.3 pngjs@5.0.0: {} @@ -11661,18 +11614,18 @@ snapshots: postcss-load-config@4.0.2(postcss@8.5.6): dependencies: lilconfig: 3.1.3 - yaml: 2.8.1 + yaml: 2.8.0 optionalDependencies: postcss: 8.5.6 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(yaml@2.8.1): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(yaml@2.8.0): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 postcss: 8.5.6 - tsx: 4.20.5 - yaml: 2.8.1 + tsx: 4.20.3 + yaml: 2.8.0 postcss-nested@6.2.0(postcss@8.5.6): dependencies: @@ -11698,9 +11651,7 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - preact@10.24.2: {} - - preact@10.27.1: {} + preact@10.26.9: {} prelude-ls@1.2.1: {} @@ -11775,14 +11726,14 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - react-dom@19.1.1(react@19.1.1): + react-dom@19.1.0(react@19.1.0): dependencies: - react: 19.1.1 + react: 19.1.0 scheduler: 0.26.0 react-is@16.13.1: {} - react@19.1.1: {} + react@19.1.0: {} read-cache@1.0.0: dependencies: @@ -11877,34 +11828,33 @@ snapshots: reusify@1.1.0: {} - rollup@4.50.0: + rollup@4.44.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.50.0 - '@rollup/rollup-android-arm64': 4.50.0 - '@rollup/rollup-darwin-arm64': 4.50.0 - '@rollup/rollup-darwin-x64': 4.50.0 - '@rollup/rollup-freebsd-arm64': 4.50.0 - '@rollup/rollup-freebsd-x64': 4.50.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.50.0 - '@rollup/rollup-linux-arm-musleabihf': 4.50.0 - '@rollup/rollup-linux-arm64-gnu': 4.50.0 - '@rollup/rollup-linux-arm64-musl': 4.50.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.50.0 - '@rollup/rollup-linux-ppc64-gnu': 4.50.0 - '@rollup/rollup-linux-riscv64-gnu': 4.50.0 - '@rollup/rollup-linux-riscv64-musl': 4.50.0 - '@rollup/rollup-linux-s390x-gnu': 4.50.0 - '@rollup/rollup-linux-x64-gnu': 4.50.0 - '@rollup/rollup-linux-x64-musl': 4.50.0 - '@rollup/rollup-openharmony-arm64': 4.50.0 - '@rollup/rollup-win32-arm64-msvc': 4.50.0 - '@rollup/rollup-win32-ia32-msvc': 4.50.0 - '@rollup/rollup-win32-x64-msvc': 4.50.0 + '@rollup/rollup-android-arm-eabi': 4.44.0 + '@rollup/rollup-android-arm64': 4.44.0 + '@rollup/rollup-darwin-arm64': 4.44.0 + '@rollup/rollup-darwin-x64': 4.44.0 + '@rollup/rollup-freebsd-arm64': 4.44.0 + '@rollup/rollup-freebsd-x64': 4.44.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.44.0 + '@rollup/rollup-linux-arm-musleabihf': 4.44.0 + '@rollup/rollup-linux-arm64-gnu': 4.44.0 + '@rollup/rollup-linux-arm64-musl': 4.44.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.44.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.44.0 + '@rollup/rollup-linux-riscv64-gnu': 4.44.0 + '@rollup/rollup-linux-riscv64-musl': 4.44.0 + '@rollup/rollup-linux-s390x-gnu': 4.44.0 + '@rollup/rollup-linux-x64-gnu': 4.44.0 + '@rollup/rollup-linux-x64-musl': 4.44.0 + '@rollup/rollup-win32-arm64-msvc': 4.44.0 + '@rollup/rollup-win32-ia32-msvc': 4.44.0 + '@rollup/rollup-win32-x64-msvc': 4.44.0 fsevents: 2.3.3 - rpc-websockets@9.1.3: + rpc-websockets@9.1.1: dependencies: '@swc/helpers': 0.5.17 '@types/uuid': 8.3.4 @@ -11912,7 +11862,7 @@ snapshots: buffer: 6.0.3 eventemitter3: 5.0.1 uuid: 8.3.2 - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: bufferutil: 4.0.9 utf-8-validate: 5.0.10 @@ -12013,40 +11963,38 @@ snapshots: setprototypeof@1.2.0: {} - sha.js@2.4.12: + sha.js@2.4.11: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 - to-buffer: 1.2.1 - sharp@0.34.3: + sharp@0.34.2: dependencies: color: 4.2.3 detect-libc: 2.0.4 semver: 7.7.2 optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.3 - '@img/sharp-darwin-x64': 0.34.3 - '@img/sharp-libvips-darwin-arm64': 1.2.0 - '@img/sharp-libvips-darwin-x64': 1.2.0 - '@img/sharp-libvips-linux-arm': 1.2.0 - '@img/sharp-libvips-linux-arm64': 1.2.0 - '@img/sharp-libvips-linux-ppc64': 1.2.0 - '@img/sharp-libvips-linux-s390x': 1.2.0 - '@img/sharp-libvips-linux-x64': 1.2.0 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 - '@img/sharp-libvips-linuxmusl-x64': 1.2.0 - '@img/sharp-linux-arm': 0.34.3 - '@img/sharp-linux-arm64': 0.34.3 - '@img/sharp-linux-ppc64': 0.34.3 - '@img/sharp-linux-s390x': 0.34.3 - '@img/sharp-linux-x64': 0.34.3 - '@img/sharp-linuxmusl-arm64': 0.34.3 - '@img/sharp-linuxmusl-x64': 0.34.3 - '@img/sharp-wasm32': 0.34.3 - '@img/sharp-win32-arm64': 0.34.3 - '@img/sharp-win32-ia32': 0.34.3 - '@img/sharp-win32-x64': 0.34.3 + '@img/sharp-darwin-arm64': 0.34.2 + '@img/sharp-darwin-x64': 0.34.2 + '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-linux-arm': 0.34.2 + '@img/sharp-linux-arm64': 0.34.2 + '@img/sharp-linux-s390x': 0.34.2 + '@img/sharp-linux-x64': 0.34.2 + '@img/sharp-linuxmusl-arm64': 0.34.2 + '@img/sharp-linuxmusl-x64': 0.34.2 + '@img/sharp-wasm32': 0.34.2 + '@img/sharp-win32-arm64': 0.34.2 + '@img/sharp-win32-ia32': 0.34.2 + '@img/sharp-win32-x64': 0.34.2 optional: true shebang-command@2.0.0: @@ -12130,9 +12078,9 @@ snapshots: spdx-expression-parse@4.0.0: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.22 + spdx-license-ids: 3.0.21 - spdx-license-ids@3.0.22: {} + spdx-license-ids@3.0.21: {} split-on-first@1.1.0: {} @@ -12159,6 +12107,8 @@ snapshots: stream-shift@1.0.3: {} + streamsearch@1.1.0: {} + strict-uri-encode@2.0.0: {} string-width@4.2.3: @@ -12237,7 +12187,7 @@ snapshots: strip-ansi@7.1.0: dependencies: - ansi-regex: 6.2.0 + ansi-regex: 6.1.0 strip-bom@3.0.0: {} @@ -12247,16 +12197,16 @@ snapshots: dependencies: js-tokens: 9.0.1 - styled-jsx@5.1.6(@babel/core@7.28.3)(react@19.1.1): + styled-jsx@5.1.6(@babel/core@7.27.4)(react@19.1.0): dependencies: client-only: 0.0.1 - react: 19.1.1 + react: 19.1.0 optionalDependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.27.4 sucrase@3.35.0: dependencies: - '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/gen-mapping': 0.3.8 commander: 4.1.1 glob: 10.4.5 lines-and-columns: 1.2.4 @@ -12280,17 +12230,17 @@ snapshots: dependencies: '@trysound/sax': 0.2.0 commander: 7.2.0 - css-select: 5.2.2 + css-select: 5.1.0 css-tree: 2.3.1 - css-what: 6.2.2 + css-what: 6.1.0 csso: 5.0.5 picocolors: 1.1.1 symbol-tree@3.2.4: {} - synckit@0.11.11: + synckit@0.11.8: dependencies: - '@pkgr/core': 0.2.9 + '@pkgr/core': 0.2.7 tailwind-merge@2.6.0: {} @@ -12341,8 +12291,8 @@ snapshots: tinyglobby@0.2.14: dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 tinypool@1.1.1: {} @@ -12356,12 +12306,6 @@ snapshots: dependencies: tldts-core: 6.1.86 - to-buffer@1.2.1: - dependencies: - isarray: 2.0.5 - safe-buffer: 5.2.1 - typed-array-buffer: 1.0.3 - to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -12384,15 +12328,19 @@ snapshots: tree-kill@1.2.2: {} - ts-api-utils@2.1.0(typescript@5.9.2): + ts-api-utils@2.1.0(typescript@5.8.3): dependencies: - typescript: 5.9.2 + typescript: 5.8.3 + + ts-essentials@10.1.1(typescript@5.8.3): + optionalDependencies: + typescript: 5.8.3 ts-interface-checker@0.1.13: {} - tsconfck@3.1.6(typescript@5.9.2): + tsconfck@3.1.6(typescript@5.8.3): optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 tsconfig-paths@3.15.0: dependencies: @@ -12405,20 +12353,20 @@ snapshots: tslib@2.8.1: {} - tsup@8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1): + tsup@8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0): dependencies: - bundle-require: 5.1.0(esbuild@0.25.9) + bundle-require: 5.1.0(esbuild@0.25.5) cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.2 debug: 4.4.1 - esbuild: 0.25.9 + esbuild: 0.25.5 fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(yaml@2.8.1) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(yaml@2.8.0) resolve-from: 5.0.0 - rollup: 4.50.0 + rollup: 4.44.0 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tinyexec: 0.3.2 @@ -12426,46 +12374,46 @@ snapshots: tree-kill: 1.2.2 optionalDependencies: postcss: 8.5.6 - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - jiti - supports-color - tsx - yaml - tsx@4.20.5: + tsx@4.20.3: dependencies: - esbuild: 0.25.9 + esbuild: 0.25.5 get-tsconfig: 4.10.1 optionalDependencies: fsevents: 2.3.3 - turbo-darwin-64@2.5.6: + turbo-darwin-64@2.5.4: optional: true - turbo-darwin-arm64@2.5.6: + turbo-darwin-arm64@2.5.4: optional: true - turbo-linux-64@2.5.6: + turbo-linux-64@2.5.4: optional: true - turbo-linux-arm64@2.5.6: + turbo-linux-arm64@2.5.4: optional: true - turbo-windows-64@2.5.6: + turbo-windows-64@2.5.4: optional: true - turbo-windows-arm64@2.5.6: + turbo-windows-arm64@2.5.4: optional: true - turbo@2.5.6: + turbo@2.5.4: optionalDependencies: - turbo-darwin-64: 2.5.6 - turbo-darwin-arm64: 2.5.6 - turbo-linux-64: 2.5.6 - turbo-linux-arm64: 2.5.6 - turbo-windows-64: 2.5.6 - turbo-windows-arm64: 2.5.6 + turbo-darwin-64: 2.5.4 + turbo-darwin-arm64: 2.5.4 + turbo-linux-64: 2.5.4 + turbo-linux-arm64: 2.5.4 + turbo-windows-64: 2.5.4 + turbo-windows-arm64: 2.5.4 type-check@0.4.0: dependencies: @@ -12509,7 +12457,7 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript@5.9.2: {} + typescript@5.8.3: {} ufo@1.6.1: {} @@ -12528,7 +12476,7 @@ snapshots: undici-types@6.21.0: {} - undici-types@7.15.0: {} + undici-types@7.16.0: {} unicode-canonical-property-names-ecmascript@2.0.1: {} @@ -12543,47 +12491,46 @@ snapshots: unpipe@1.0.0: {} - unrs-resolver@1.11.1: + unrs-resolver@1.9.2: dependencies: - napi-postinstall: 0.3.3 + napi-postinstall: 0.2.4 optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.11.1 - '@unrs/resolver-binding-android-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-x64': 1.11.1 - '@unrs/resolver-binding-freebsd-x64': 1.11.1 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 - '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-musl': 1.11.1 - '@unrs/resolver-binding-wasm32-wasi': 1.11.1 - '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 - '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 - '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - - unstorage@1.17.0(@vercel/functions@2.2.13)(idb-keyval@6.2.2): + '@unrs/resolver-binding-android-arm-eabi': 1.9.2 + '@unrs/resolver-binding-android-arm64': 1.9.2 + '@unrs/resolver-binding-darwin-arm64': 1.9.2 + '@unrs/resolver-binding-darwin-x64': 1.9.2 + '@unrs/resolver-binding-freebsd-x64': 1.9.2 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.9.2 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.9.2 + '@unrs/resolver-binding-linux-arm64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-arm64-musl': 1.9.2 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-riscv64-musl': 1.9.2 + '@unrs/resolver-binding-linux-s390x-gnu': 1.9.2 + '@unrs/resolver-binding-linux-x64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-x64-musl': 1.9.2 + '@unrs/resolver-binding-wasm32-wasi': 1.9.2 + '@unrs/resolver-binding-win32-arm64-msvc': 1.9.2 + '@unrs/resolver-binding-win32-ia32-msvc': 1.9.2 + '@unrs/resolver-binding-win32-x64-msvc': 1.9.2 + + unstorage@1.16.0(idb-keyval@6.2.2): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 destr: 2.0.5 - h3: 1.15.4 + h3: 1.15.3 lru-cache: 10.4.3 - node-fetch-native: 1.6.7 + node-fetch-native: 1.6.6 ofetch: 1.4.1 ufo: 1.6.1 optionalDependencies: - '@vercel/functions': 2.2.13 idb-keyval: 6.2.2 - update-browserslist-db@1.1.3(browserslist@4.25.4): + update-browserslist-db@1.1.3(browserslist@4.25.0): dependencies: - browserslist: 4.25.4 + browserslist: 4.25.0 escalade: 3.2.0 picocolors: 1.1.1 @@ -12591,13 +12538,13 @@ snapshots: dependencies: punycode: 2.3.1 - use-sync-external-store@1.2.0(react@19.1.1): + use-sync-external-store@1.2.0(react@19.1.0): dependencies: - react: 19.1.1 + react: 19.1.0 - use-sync-external-store@1.4.0(react@19.1.1): + use-sync-external-store@1.4.0(react@19.1.0): dependencies: - react: 19.1.1 + react: 19.1.0 utf-8-validate@5.0.10: dependencies: @@ -12619,75 +12566,75 @@ snapshots: uuid@9.0.1: {} - valtio@1.13.2(@types/react@19.1.12)(react@19.1.1): + valtio@1.13.2(@types/react@19.1.8)(react@19.1.0): dependencies: - derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.1.12)(react@19.1.1)) + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.1.8)(react@19.1.0)) proxy-compare: 2.6.0 - use-sync-external-store: 1.2.0(react@19.1.1) + use-sync-external-store: 1.2.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.12 - react: 19.1.1 + '@types/react': 19.1.8 + react: 19.1.0 vary@1.1.2: {} - viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76): + viem@2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67): dependencies: '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@scure/bip32': 1.6.2 '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.9.2)(zod@3.25.76) + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.67) isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.6.7(typescript@5.9.2)(zod@3.25.76) + ox: 0.6.7(typescript@5.8.3)(zod@3.25.67) ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - bufferutil - utf-8-validate - zod - viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4): + viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4): dependencies: - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.2)(zod@3.22.4) - isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.9.3(typescript@5.9.2)(zod@3.22.4) - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + isows: 1.0.7(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.8.1(typescript@5.8.3)(zod@3.22.4) + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - bufferutil - utf-8-validate - zod - viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76): + viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67): dependencies: - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.2)(zod@3.25.76) - isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.9.3(typescript@5.9.2)(zod@3.25.76) - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.67) + isows: 1.0.7(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.8.1(typescript@5.8.3)(zod@3.25.67) + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - bufferutil - utf-8-validate - zod - vite-node@3.2.4(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1): + vite-node@3.2.4(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0): dependencies: cac: 6.7.14 debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite: 6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -12702,60 +12649,66 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)): dependencies: debug: 4.4.1 globrex: 0.1.2 - tsconfck: 3.1.6(typescript@5.9.2) + tsconfck: 3.1.6(typescript@5.8.3) optionalDependencies: - vite: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite: 6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - supports-color - typescript - vite@6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1): + vite@6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0): dependencies: - esbuild: 0.25.9 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + esbuild: 0.25.5 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 postcss: 8.5.6 - rollup: 4.50.0 + rollup: 4.44.0 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 22.18.0 + '@types/node': 22.15.33 fsevents: 2.3.3 jiti: 1.21.7 - tsx: 4.20.5 - yaml: 2.8.1 + tsx: 4.20.3 + yaml: 2.8.0 + + vitest-mock-extended@3.1.0(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.33)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.3)(yaml@2.8.0)): + dependencies: + ts-essentials: 10.1.1(typescript@5.8.3) + typescript: 5.8.3 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.33)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.3)(yaml@2.8.0) - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.0)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.33)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.3)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.3.3 + chai: 5.2.0 debug: 4.4.1 - expect-type: 1.2.2 - magic-string: 0.30.18 + expect-type: 1.2.1 + magic-string: 0.30.17 pathe: 2.0.3 - picomatch: 4.0.3 + picomatch: 4.0.2 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite: 6.3.5(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@22.15.33)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 22.18.0 + '@types/node': 22.15.33 jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - jiti @@ -12775,16 +12728,16 @@ snapshots: dependencies: xml-name-validator: 5.0.0 - wagmi@2.16.9(@tanstack/query-core@5.85.9)(@tanstack/react-query@5.85.9(react@19.1.1))(@types/react@19.1.12)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): + wagmi@2.15.6(@tanstack/query-core@5.81.2)(@tanstack/react-query@5.81.2(react@19.1.0))(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67))(zod@3.25.67): dependencies: - '@tanstack/react-query': 5.85.9(react@19.1.1) - '@wagmi/connectors': 5.9.9(@types/react@19.1.12)(@vercel/functions@2.2.13)(@wagmi/core@2.20.3(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) - '@wagmi/core': 2.20.3(@tanstack/query-core@5.85.9)(@types/react@19.1.12)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - react: 19.1.1 - use-sync-external-store: 1.4.0(react@19.1.1) - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@tanstack/react-query': 5.81.2(react@19.1.0) + '@wagmi/connectors': 5.8.5(@types/react@19.1.8)(@wagmi/core@2.17.3(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)))(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67))(zod@3.25.67) + '@wagmi/core': 2.17.3(@tanstack/query-core@5.81.2)(@types/react@19.1.8)(react@19.1.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67)) + react: 19.1.0 + use-sync-external-store: 1.4.0(react@19.1.0) + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) optionalDependencies: - typescript: 5.9.2 + typescript: 5.8.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -12801,7 +12754,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -12933,19 +12885,19 @@ snapshots: bufferutil: 4.0.9 utf-8-validate: 5.0.10 - ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10): optionalDependencies: bufferutil: 4.0.9 utf-8-validate: 5.0.10 - x402@0.1.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10): + x402@0.1.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10): dependencies: - '@hono/node-server': 1.19.1(hono@4.9.6) - axios: 1.11.0 + '@hono/node-server': 1.14.4(hono@4.8.2) + axios: 1.10.0 express: 4.21.2 - hono: 4.9.6 - viem: 2.37.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zod: 3.25.76 + hono: 4.8.2 + viem: 2.31.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.67) + zod: 3.25.67 transitivePeerDependencies: - bufferutil - debug @@ -12965,7 +12917,7 @@ snapshots: yallist@3.1.1: {} - yaml@2.8.1: {} + yaml@2.8.0: {} yargs-parser@18.1.3: dependencies: @@ -12990,16 +12942,10 @@ snapshots: zod@3.22.4: {} - zod@3.25.76: {} - - zustand@5.0.0(@types/react@19.1.12)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): - optionalDependencies: - '@types/react': 19.1.12 - react: 19.1.1 - use-sync-external-store: 1.4.0(react@19.1.1) + zod@3.25.67: {} - zustand@5.0.3(@types/react@19.1.12)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): + zustand@5.0.0(@types/react@19.1.8)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)): optionalDependencies: - '@types/react': 19.1.12 - react: 19.1.1 - use-sync-external-store: 1.4.0(react@19.1.1) + '@types/react': 19.1.8 + react: 19.1.0 + use-sync-external-store: 1.4.0(react@19.1.0) From 3c905fcf536c91f104954ce3e49f8e780c829d6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 13 Aug 2025 17:23:13 -0300 Subject: [PATCH 037/116] feat: implement split verify for deferred MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-express/src/index.ts | 128 +++++++++++------- .../x402/src/schemes/deferred/evm/id.ts | 12 ++ .../x402/src/schemes/deferred/evm/index.ts | 1 + 3 files changed, 91 insertions(+), 50 deletions(-) create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/id.ts diff --git a/typescript/packages/x402-express/src/index.ts b/typescript/packages/x402-express/src/index.ts index 83f6751434..e39f5a97ee 100644 --- a/typescript/packages/x402-express/src/index.ts +++ b/typescript/packages/x402-express/src/index.ts @@ -352,61 +352,85 @@ export function paymentMiddleware( } /** - * Creates a deferred payment middleware factory for Express + * Creates a deferred payment middleware factory for Express. + * + * Note: this middleware only performs x402 verification. In the deferred scheme, + * settlement does not happen as part of the x402 resource request handshake. + * + * The middleware requires two server-implemented functions, executed before and after + * x402 verification: + * - retrieveVoucher: Before verification, retrieves the latest voucher for a given + * buyer/seller. Used to determine whether to create a new voucher or aggregate + * into the existing one. + * - storeVoucher: After verification, allows the server to persist the newly created + * voucher. This can be stored locally or via a third-party service. * * @param payTo - The address to receive payments * @param routes - Configuration for protected routes and their payment requirements - * @param getLatestVoucher - A function to get the latest voucher for a given buyer and seller. Needs to be implemented by the server. + * @param retrieveVoucher - A function to get the latest voucher for a given buyer and seller. Needs to be implemented by the server. * @param escrow - The escrow address + * @param storeVoucher - A function to store the voucher. Needs to be implemented by the server. * @param facilitator - Optional configuration for the payment facilitator service * @returns An Express middleware handler * * @example * ```typescript - * // Simple configuration - All endpoints are protected by $0.01 of USDC on base-sepolia - * app.use(deferredPaymentMiddleware( - * '0x123...', // payTo address - * { - * price: '$0.01', // USDC amount in dollars - * network: 'base-sepolia' - * }, - * // Optional facilitator configuration. Defaults to x402.org/facilitator for testnet usage - * )); + * // Simple configuration — all endpoints protected by $0.01 of USDC on Base Sepolia + * app.use( + * deferredPaymentMiddleware( + * '0x123...', // payTo address + * { + * price: '$0.01', // USDC amount in dollars + * network: 'base-sepolia', + * }, + * retrieveVoucher, + * '0xescrowAddress...', + * storeVoucher, + * // Optional facilitator configuration (defaults to x402.org/facilitator for testnet usage) + * ) + * ); * - * // Advanced configuration - Endpoint-specific payment requirements & custom facilitator - * app.use(deferredPaymentMiddleware('0x123...', // payTo: The address to receive payments* { - * { - * '/weather/*': { - * price: '$0.001', // USDC amount in dollars - * network: 'base', - * config: { - * description: 'Access to weather data' - * } + * // Advanced configuration — endpoint-specific requirements & custom facilitator + * app.use( + * deferredPaymentMiddleware( + * '0x123...', // payTo + * { + * '/weather/*': { + * price: '$0.001', // USDC amount in dollars + * network: 'base', + * config: { + * description: 'Access to weather data', + * }, + * }, + * }, + * retrieveVoucher, + * '0xescrowAddress...', + * storeVoucher, + * { + * url: 'https://facilitator.example.com', + * createAuthHeaders: async () => ({ + * verify: { Authorization: 'Bearer token' }, + * settle: { Authorization: 'Bearer token' }, + * }), + * }, + * { + * cdpClientKey: 'your-cdp-client-key', + * appLogo: '/images/logo.svg', + * appName: 'My App', * } - * }, - * { - * url: 'https://facilitator.example.com', - * createAuthHeaders: async () => ({ - * verify: { "Authorization": "Bearer token" }, - * settle: { "Authorization": "Bearer token" } - * }) - * }, - * { - * cdpClientKey: 'your-cdp-client-key', - * appLogo: '/images/logo.svg', - * appName: 'My App', - * } - * )); + * ) + * ); * ``` */ export function deferredPaymentMiddleware( payTo: Address, routes: RoutesConfig, - getLatestVoucher: ( + retrieveVoucher: ( buyer: string, seller: string, ) => Promise<(DeferredEvmPayloadVoucher & { signature: string }) | null>, escrow: Address, + storeVoucher: (voucher: DeferredEvmPayloadVoucher, signature: string) => Promise, facilitator?: FacilitatorConfig, ) { const { verify } = useFacilitator(facilitator); @@ -458,7 +482,7 @@ export function deferredPaymentMiddleware( paymentBuyer, payTo, escrow, - getLatestVoucher, + retrieveVoucher, ), }, ]; @@ -527,20 +551,24 @@ export function deferredPaymentMiddleware( return; } + try { + const { voucher, signature } = DeferredEvmPayloadSchema.parse(decodedPayment.payload); + await storeVoucher(voucher, signature); + } catch (error) { + console.error(error); + res.status(402).json({ + x402Version, + error, + accepts: toJsonSafe(paymentRequirements), + }); + return; + } + // Proceed to the next middleware or route handler next(); }; } -/** - * Generate a new voucher id - * - * @returns A new voucher id - */ -function generateVoucherId() { - return `0x${Date.now().toString(16)}${Math.random().toString(16).slice(2)}`.padEnd(66, "0"); -} - /** * Get the extra data for the payment requirements * @@ -548,7 +576,7 @@ function generateVoucherId() { * @param paymentBuyerHeader - The x-payment-buyer header * @param seller - The seller address * @param escrow - The escrow address - * @param getLatestVoucher - A function to get the latest voucher for a given buyer and seller. + * @param retrieveVoucher - A function to get the latest voucher for a given buyer and seller. * @returns The extra data for the payment requirements */ async function getPaymentRequirementsExtra( @@ -556,7 +584,7 @@ async function getPaymentRequirementsExtra( paymentBuyerHeader: string | undefined, seller: Address, escrow: Address, - getLatestVoucher: ( + retrieveVoucher: ( buyer: string, seller: string, ) => Promise<(DeferredEvmPayloadVoucher & { signature: string }) | null>, @@ -564,7 +592,7 @@ async function getPaymentRequirementsExtra( const newVoucher = { type: "new" as const, voucher: { - id: generateVoucherId(), + id: deferred.evm.generateVoucherId(), escrow, }, }; @@ -572,7 +600,7 @@ async function getPaymentRequirementsExtra( // No header, new voucher if (!paymentHeader) { if (paymentBuyerHeader) { - const latestVoucher = await getLatestVoucher(paymentBuyerHeader, seller); + const latestVoucher = await retrieveVoucher(paymentBuyerHeader, seller); // No voucher history, new voucher if (!latestVoucher) { @@ -600,7 +628,7 @@ async function getPaymentRequirementsExtra( } // Get the latest voucher for the buyer - const latestVoucher = await getLatestVoucher(paymentRequirements.data.voucher.buyer, seller); + const latestVoucher = await retrieveVoucher(paymentRequirements.data.voucher.buyer, seller); // No voucher history, new voucher if (!latestVoucher) { diff --git a/typescript/packages/x402/src/schemes/deferred/evm/id.ts b/typescript/packages/x402/src/schemes/deferred/evm/id.ts new file mode 100644 index 0000000000..c13ff8a6d6 --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/id.ts @@ -0,0 +1,12 @@ +import crypto from "crypto"; + +/** + * Generate a 64-character hexadecimal voucher ID + * + * @returns A new voucher id (0x-prefixed) + */ +export function generateVoucherId(): string { + // 32 bytes = 64 hex characters + const bytes = crypto.randomBytes(32); + return `0x${bytes.toString("hex")}`; +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/index.ts b/typescript/packages/x402/src/schemes/deferred/evm/index.ts index 7566034e4e..cbf4e06dfc 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/index.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/index.ts @@ -1,4 +1,5 @@ export * from "./client"; export * from "./facilitator"; +export * from "./id"; export * from "./sign"; export * from "./utils/paymentUtils"; From 989fa11f637117be19be6dfe6aefe3d056e0279f Mon Sep 17 00:00:00 2001 From: Pablo Carranza Velez Date: Thu, 31 Jul 2025 16:47:19 -0300 Subject: [PATCH 038/116] docs: add Python deferred payment scheme implementation plan --- python/deferred_implementation_plan.md | 105 +++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 python/deferred_implementation_plan.md diff --git a/python/deferred_implementation_plan.md b/python/deferred_implementation_plan.md new file mode 100644 index 0000000000..e1b57bf3ec --- /dev/null +++ b/python/deferred_implementation_plan.md @@ -0,0 +1,105 @@ +# Python Deferred Payment Scheme Implementation Plan + +## Overview +This document outlines the implementation plan for adding deferred payment scheme support to the Python x402 client, based on the existing TypeScript implementation. + +## Implementation Steps + +### 1. Add Type Definitions (types.py) + +Add the following new types to support deferred payments: + +```python +class DeferredEvmPayloadVoucher(BaseModel): + id: str # Hex encoded 64 bytes (bytes32) + buyer: str # EVM address + seller: str # EVM address + value_aggregate: str # Total outstanding amount, monotonically increasing + asset: str # ERC-20 token address + timestamp: int # Unix timestamp + nonce: int # Incremented with each aggregation + escrow: str # Escrow contract address + chain_id: int # Network chain ID + expiry: int # Expiration timestamp + +class DeferredPaymentPayload(BaseModel): + signature: str + voucher: DeferredEvmPayloadVoucher + +class DeferredPaymentRequirementsExtraNewVoucher(BaseModel): + type: Literal["new"] + voucher: dict # Contains only 'id' and 'escrow' fields + +class DeferredPaymentRequirementsExtraAggregationVoucher(BaseModel): + type: Literal["aggregation"] + signature: str + voucher: DeferredEvmPayloadVoucher + +# Update SchemePayloads union +SchemePayloads = Union[ExactPaymentPayload, DeferredPaymentPayload] +``` + +### 2. Create Deferred Module (deferred.py) + +Implement core deferred payment functionality: + +```python +# Constants +EXPIRY_TIME = 60 * 60 * 24 * 30 # 30 days +DEFERRED_SCHEME = "deferred" + +# Core functions +def prepare_payment_header(sender_address, x402_version, payment_requirements) +def create_new_voucher(buyer, payment_requirements) +def aggregate_voucher(buyer, payment_requirements) +def sign_voucher(account, voucher) +def verify_voucher(voucher, signature, signer) +def sign_payment_header(account, payment_requirements, header) +def encode_payment(payment_payload) +``` + +### 3. EIP-712 Typed Data Structure + +The deferred scheme uses different typed data: +- Domain: "DeferredPaymentEscrow" (vs "EIP712Domain" for exact) +- Primary type: Custom voucher structure (vs "TransferWithAuthorization") +- Message fields: id, buyer, seller, valueAggregate, asset, timestamp, nonce, escrow, chainId, expiry + +### 4. Update Client Integration + +Modify client code to: +- Detect scheme type from payment requirements +- Route to appropriate payment header creation function +- Handle both new voucher creation and aggregation flows + +### 5. Testing Requirements + +- Unit tests for voucher creation and aggregation +- EIP-712 signature verification tests +- Integration tests with httpx/requests clients +- Edge cases: expired vouchers, invalid signatures, timestamp validation + +## Key Differences from Exact Scheme + +1. **Voucher-based**: Uses signed vouchers instead of EIP-3009 authorizations +2. **Aggregation**: Supports increasing payment amounts over time +3. **Escrow model**: Funds are pre-deposited in escrow contract +4. **Expiry handling**: Vouchers have expiration timestamps +5. **Nonce management**: Increments with each aggregation (not random) + +## TODO Items for MVP + +- [ ] Implement basic voucher creation and signing +- [ ] Add voucher aggregation logic +- [ ] Integrate with existing client classes +- [ ] Add comprehensive error handling +- [ ] Write unit tests for core functionality +- [ ] Add integration tests +- [ ] Update documentation + +## Future Enhancements + +- Smart account support for signature verification +- Batch voucher collection support +- Advanced expiry management +- Performance optimizations for voucher storage/retrieval \ No newline at end of file From 2f35450730f1d960fcf6692b0495e85d23e2da38 Mon Sep 17 00:00:00 2001 From: Pablo Carranza Velez Date: Thu, 31 Jul 2025 17:11:56 -0300 Subject: [PATCH 039/116] feat: add deferred payment scheme support to Python client - Add DeferredEvmPayloadVoucher and related types - Implement voucher creation, aggregation, and EIP-712 signing - Update base client to support both exact and deferred schemes - Add comprehensive unit tests for deferred payments - Fix nonce encoding bug in exact scheme - Add X-PAYMENT-BUYER header to identify buyer on initial requests - Update README with deferred payment documentation --- python/TODO.md | 75 +++++++ python/x402/README.md | 37 +++ python/x402/src/x402/clients/base.py | 61 ++--- python/x402/src/x402/clients/httpx.py | 4 +- python/x402/src/x402/clients/requests.py | 4 + python/x402/src/x402/deferred.py | 260 ++++++++++++++++++++++ python/x402/src/x402/exact.py | 2 +- python/x402/src/x402/types.py | 72 +++++- python/x402/tests/test_deferred.py | 272 +++++++++++++++++++++++ 9 files changed, 757 insertions(+), 30 deletions(-) create mode 100644 python/TODO.md create mode 100644 python/x402/src/x402/deferred.py create mode 100644 python/x402/tests/test_deferred.py diff --git a/python/TODO.md b/python/TODO.md new file mode 100644 index 0000000000..0e23e32aa0 --- /dev/null +++ b/python/TODO.md @@ -0,0 +1,75 @@ +# Python Deferred Payment Scheme - TODO + +## What we built + +✅ **Completed:** +- Added new type definitions for deferred payments: + - `DeferredEvmPayloadVoucher` - Full voucher structure with all fields + - `DeferredPaymentPayload` - Payload containing signature and voucher + - `DeferredPaymentRequirementsExtra*` - Discriminated unions for new/aggregation + - Updated `SchemePayloads` union to include deferred + +- Created `deferred.py` module with: + - `prepare_payment_header()` - Creates unsigned deferred payments + - `create_new_voucher()` - Creates new vouchers with initial valueAggregate + - `aggregate_voucher()` - Aggregates existing vouchers (increments valueAggregate) + - `sign_voucher()` - EIP-712 signing for DeferredPaymentEscrow domain + - `verify_voucher()` - Verifies voucher signatures + - Full encode/decode support + +- Updated client integration: + - Modified `base.py` to support both exact and deferred schemes + - Added scheme detection and routing in `create_payment_header()` + - Updated payment requirements selector to accept deferred + +- Wrote comprehensive unit tests (test_deferred.py): + - New voucher creation + - Voucher signing and verification + - Voucher aggregation with validation + - Expired voucher handling + - Encoding/decoding + +## Things to fix eventually + +### High Priority +- [x] Test runner setup - Tests are now passing with uv +- [x] Fixed nonce encoding bug in exact.py (was returning bytes instead of hex) +- [ ] Integration tests with actual HTTP clients (httpx/requests) +- [ ] Verify EIP-712 signature format matches TypeScript exactly +- [ ] Add proper error handling for network errors during aggregation + +### Medium Priority +- [ ] Add support for smart account signature verification (noted in TypeScript TODO) +- [ ] Implement batch voucher collection support (collectMany) +- [ ] Add voucher storage/retrieval helpers for managing multiple vouchers +- [ ] Performance optimization for voucher lookups + +### Low Priority +- [ ] Add comprehensive logging for debugging +- [ ] Create example scripts showing deferred payment flows +- [ ] Document differences between exact and deferred schemes +- [ ] Add type hints for all function parameters + +## Security Notes + +⚠️ **Important security considerations:** +- Voucher signatures MUST be verified before aggregation +- Expiry timestamps need to be checked to prevent expired voucher usage +- Chain ID validation is critical to prevent cross-chain replay attacks +- Value aggregation must be monotonically increasing +- Currently assumes trusted input for voucher data - needs validation in production + +## Testing Notes + +The test suite covers the core functionality but hasn't been run yet due to environment setup. Before using in production: +1. Run full test suite +2. Add integration tests with real escrow contracts +3. Test edge cases around timestamp boundaries +4. Verify signature compatibility with TypeScript implementation + +## Implementation Notes + +- Used eth_account for EIP-712 signing (same as exact scheme) +- Followed TypeScript structure closely for compatibility +- 30-day default expiry matches TypeScript +- Checksum addresses used throughout for consistency \ No newline at end of file diff --git a/python/x402/README.md b/python/x402/README.md index f6441e9f2f..9c790d9553 100644 --- a/python/x402/README.md +++ b/python/x402/README.md @@ -80,6 +80,43 @@ payment_middleware.add( ) ``` +## Payment Schemes + +The x402 protocol supports multiple payment schemes. Currently supported: + +- **`exact`**: Traditional EIP-3009 payments with immediate settlement +- **`deferred`**: Voucher-based payments with aggregation and batch settlement + +### Deferred Payment Scheme + +The deferred scheme enables efficient micropayments by allowing sellers to accumulate signed vouchers and redeem them in batches: + +```py +# The client automatically handles both exact and deferred schemes +# based on the server's payment requirements + +from eth_account import Account +from x402.clients.httpx import x402HttpxClient + +account = Account.from_key("your_private_key") + +async with x402HttpxClient(account=account, base_url="https://api.example.com") as client: + # First request creates a new voucher + response1 = await client.get("/api/endpoint") + + # Subsequent requests aggregate to the same voucher + response2 = await client.get("/api/endpoint") + + # The valueAggregate increases with each request + # Seller can batch redeem vouchers later +``` + +Key features of deferred payments: +- Vouchers are aggregated offchain, reducing gas costs +- Value accumulates monotonically (always increases) +- 30-day default expiry for vouchers +- Sellers batch redeem when it's economically efficient + ## Client Integration ### Simple Usage diff --git a/python/x402/src/x402/clients/base.py b/python/x402/src/x402/clients/base.py index e2e8c1023e..7d18392153 100644 --- a/python/x402/src/x402/clients/base.py +++ b/python/x402/src/x402/clients/base.py @@ -1,7 +1,9 @@ -import time from typing import Optional, Callable, Dict, Any, List from eth_account import Account -from x402.exact import sign_payment_header +from x402.exact import sign_payment_header as sign_exact_payment_header +from x402.exact import prepare_payment_header as prepare_exact_payment_header +from x402.deferred import sign_payment_header as sign_deferred_payment_header +from x402.deferred import prepare_payment_header as prepare_deferred_payment_header from x402.types import ( PaymentRequirements, UnsupportedSchemeException, @@ -116,7 +118,7 @@ def default_payment_requirements_selector( if network_filter and network != network_filter: continue - if scheme == "exact": + if scheme in ["exact", "deferred"]: # Check max value if set if max_value is not None: max_amount = int(paymentRequirements.max_amount_required) @@ -167,30 +169,35 @@ def create_payment_header( Returns: Signed payment header """ - unsigned_header = { - "x402Version": x402_version, - "scheme": payment_requirements.scheme, - "network": payment_requirements.network, - "payload": { - "signature": None, - "authorization": { - "from": self.account.address, - "to": payment_requirements.pay_to, - "value": payment_requirements.max_amount_required, - "validAfter": str(int(time.time()) - 60), # 60 seconds before - "validBefore": str( - int(time.time()) + payment_requirements.max_timeout_seconds - ), - "nonce": self.generate_nonce(), - }, - }, - } - - signed_header = sign_payment_header( - self.account, - payment_requirements, - unsigned_header, - ) + scheme = payment_requirements.scheme + + if scheme == "exact": + # Create exact payment header + unsigned_header = prepare_exact_payment_header( + self.account.address, + x402_version, + payment_requirements + ) + signed_header = sign_exact_payment_header( + self.account, + payment_requirements, + unsigned_header, + ) + elif scheme == "deferred": + # Create deferred payment header + unsigned_header = prepare_deferred_payment_header( + self.account.address, + x402_version, + payment_requirements + ) + signed_header = sign_deferred_payment_header( + self.account, + payment_requirements, + unsigned_header, + ) + else: + raise UnsupportedSchemeException(f"Unsupported payment scheme: {scheme}") + return signed_header def generate_nonce(self): diff --git a/python/x402/src/x402/clients/httpx.py b/python/x402/src/x402/clients/httpx.py index 430cfb8ee4..8b49e259df 100644 --- a/python/x402/src/x402/clients/httpx.py +++ b/python/x402/src/x402/clients/httpx.py @@ -17,7 +17,9 @@ def __init__(self, client: x402Client): async def on_request(self, request: Request): """Handle request before it is sent.""" - pass + # Add buyer header to identify the account + if self.client.account and hasattr(self.client.account, 'address'): + request.headers["X-PAYMENT-BUYER"] = self.client.account.address async def on_response(self, response: Response) -> Response: """Handle response after it is received.""" diff --git a/python/x402/src/x402/clients/requests.py b/python/x402/src/x402/clients/requests.py index fee5346944..27e99de437 100644 --- a/python/x402/src/x402/clients/requests.py +++ b/python/x402/src/x402/clients/requests.py @@ -36,6 +36,10 @@ def send(self, request, **kwargs): Returns: Response object """ + # Add buyer header to identify the account + if not self._is_retry and self.client.account and hasattr(self.client.account, 'address'): + request.headers["X-PAYMENT-BUYER"] = self.client.account.address + if self._is_retry: self._is_retry = False return super().send(request, **kwargs) diff --git a/python/x402/src/x402/deferred.py b/python/x402/src/x402/deferred.py new file mode 100644 index 0000000000..af84cba01e --- /dev/null +++ b/python/x402/src/x402/deferred.py @@ -0,0 +1,260 @@ +import time +import json +from typing import Dict, Any +from typing_extensions import TypedDict + +from eth_account import Account +from eth_account.messages import encode_typed_data +from eth_utils import to_checksum_address +from hexbytes import HexBytes + +from x402.encoding import safe_base64_encode, safe_base64_decode +from x402.types import ( + PaymentRequirements, + DeferredEvmPayloadVoucher, + DeferredPaymentPayload, + DeferredPaymentRequirementsExtraNewVoucher, + DeferredPaymentRequirementsExtraAggregationVoucher, +) +from x402.chains import get_chain_id + +# Constants +EXPIRY_TIME = 60 * 60 * 24 * 30 # 30 days +DEFERRED_SCHEME = "deferred" + + +class PaymentHeader(TypedDict): + x402Version: int + scheme: str + network: str + payload: dict[str, Any] + + +def prepare_payment_header( + sender_address: str, x402_version: int, payment_requirements: PaymentRequirements +) -> Dict[str, Any]: + """Prepare an unsigned deferred payment header.""" + # Check if extra is a dict and has 'type' field + if not payment_requirements.extra or "type" not in payment_requirements.extra: + raise ValueError("Payment requirements extra must contain 'type' field") + + extra_type = payment_requirements.extra["type"] + + if extra_type == "new": + voucher = create_new_voucher(sender_address, payment_requirements) + elif extra_type == "aggregation": + voucher = aggregate_voucher(sender_address, payment_requirements) + else: + raise ValueError(f"Unknown voucher type: {extra_type}") + + return { + "x402Version": x402_version, + "scheme": DEFERRED_SCHEME, + "network": payment_requirements.network, + "payload": { + "signature": None, + "voucher": voucher.model_dump(by_alias=True), + }, + } + + +def create_new_voucher( + buyer: str, payment_requirements: PaymentRequirements +) -> DeferredEvmPayloadVoucher: + """Create a new voucher with the given payment requirements.""" + # Validate extra data structure + try: + extra = DeferredPaymentRequirementsExtraNewVoucher(**payment_requirements.extra) + except Exception as e: + raise ValueError(f"Invalid extra data for new voucher: {e}") + + return DeferredEvmPayloadVoucher( + id=extra.voucher["id"], + buyer=to_checksum_address(buyer), + seller=to_checksum_address(payment_requirements.pay_to), + value_aggregate=payment_requirements.max_amount_required, + asset=to_checksum_address(payment_requirements.asset), + timestamp=int(time.time()), + nonce=0, + escrow=to_checksum_address(extra.voucher["escrow"]), + chain_id=int(get_chain_id(payment_requirements.network)), + expiry=int(time.time()) + EXPIRY_TIME, + ) + + +def aggregate_voucher( + buyer: str, payment_requirements: PaymentRequirements +) -> DeferredEvmPayloadVoucher: + """Aggregate a voucher with new payment requirements.""" + # Validate extra data structure + try: + extra = DeferredPaymentRequirementsExtraAggregationVoucher(**payment_requirements.extra) + except Exception as e: + raise ValueError(f"Invalid extra data for voucher aggregation: {e}") + + voucher = extra.voucher + now = int(time.time()) + + # Verify previous voucher matches payment requirements + if payment_requirements.pay_to.lower() != voucher.seller.lower(): + raise ValueError("Invalid voucher seller") + if payment_requirements.asset.lower() != voucher.asset.lower(): + raise ValueError("Invalid voucher asset") + if int(get_chain_id(payment_requirements.network)) != voucher.chain_id: + raise ValueError("Invalid voucher chainId") + if now > voucher.expiry: + raise ValueError("Voucher expired") + if now < voucher.timestamp: + raise ValueError("Voucher timestamp is in the future") + + # Verify signature is valid and the voucher's buyer is the client + is_valid = verify_voucher(voucher, extra.signature, buyer) + if not is_valid: + raise ValueError("Invalid voucher signature") + + # Create aggregated voucher + new_value_aggregate = str( + int(payment_requirements.max_amount_required) + int(voucher.value_aggregate) + ) + + return DeferredEvmPayloadVoucher( + id=voucher.id, + buyer=to_checksum_address(buyer), + seller=voucher.seller, + value_aggregate=new_value_aggregate, + asset=voucher.asset, + timestamp=now, + nonce=voucher.nonce + 1, + escrow=voucher.escrow, + chain_id=voucher.chain_id, + expiry=now + EXPIRY_TIME, + ) + + +def get_voucher_typed_data(voucher: DeferredEvmPayloadVoucher) -> Dict[str, Any]: + """Get the EIP-712 typed data for a voucher.""" + return { + "types": { + "EIP712Domain": [ + {"name": "name", "type": "string"}, + {"name": "version", "type": "string"}, + {"name": "chainId", "type": "uint256"}, + {"name": "verifyingContract", "type": "address"}, + ], + "Voucher": [ + {"name": "id", "type": "bytes32"}, + {"name": "buyer", "type": "address"}, + {"name": "seller", "type": "address"}, + {"name": "valueAggregate", "type": "uint256"}, + {"name": "asset", "type": "address"}, + {"name": "timestamp", "type": "uint64"}, + {"name": "nonce", "type": "uint256"}, + {"name": "escrow", "type": "address"}, + {"name": "chainId", "type": "uint256"}, + {"name": "expiry", "type": "uint64"}, + ] + }, + "primaryType": "Voucher", + "domain": { + "name": "DeferredPaymentEscrow", + "version": "1", + "chainId": voucher.chain_id, + "verifyingContract": to_checksum_address(voucher.escrow), + }, + "message": { + "id": voucher.id, + "buyer": to_checksum_address(voucher.buyer), + "seller": to_checksum_address(voucher.seller), + "valueAggregate": int(voucher.value_aggregate), + "asset": to_checksum_address(voucher.asset), + "timestamp": voucher.timestamp, + "nonce": voucher.nonce, + "escrow": to_checksum_address(voucher.escrow), + "chainId": voucher.chain_id, + "expiry": voucher.expiry, + }, + } + + +def sign_voucher(account: Account, voucher: DeferredEvmPayloadVoucher) -> str: + """Sign a voucher using EIP-712.""" + typed_data = get_voucher_typed_data(voucher) + + # Encode the typed data + signable_message = encode_typed_data( + domain_data=typed_data["domain"], + message_types={k: v for k, v in typed_data["types"].items() if k != "EIP712Domain"}, + message_data=typed_data["message"], + ) + + # Sign the message + signed_message = account.sign_message(signable_message) + signature = signed_message.signature.hex() + + if not signature.startswith("0x"): + signature = f"0x{signature}" + + return signature + + +def verify_voucher( + voucher: DeferredEvmPayloadVoucher, signature: str, signer: str +) -> bool: + """Verify a voucher signature.""" + typed_data = get_voucher_typed_data(voucher) + + # Encode the typed data + signable_message = encode_typed_data( + domain_data=typed_data["domain"], + message_types={k: v for k, v in typed_data["types"].items() if k != "EIP712Domain"}, + message_data=typed_data["message"], + ) + + # Recover the signer address + recovered_address = Account.recover_message(signable_message, signature=signature) + + return recovered_address.lower() == signer.lower() + + +def sign_payment_header( + account: Account, payment_requirements: PaymentRequirements, header: PaymentHeader +) -> str: + """Sign a deferred payment header using the account's private key.""" + try: + voucher_dict = header["payload"]["voucher"] + voucher = DeferredEvmPayloadVoucher(**voucher_dict) + + # Sign the voucher + signature = sign_voucher(account, voucher) + + # Update the header with the signature + header["payload"]["signature"] = signature + + # Encode the payment + encoded = encode_payment(header) + return encoded + except Exception as e: + raise Exception(f"Failed to sign payment header: {e}") + + +def encode_payment(payment_payload: Dict[str, Any]) -> str: + """Encode a payment payload into a base64 string.""" + from hexbytes import HexBytes + + def default(obj): + if isinstance(obj, HexBytes): + return obj.hex() + if hasattr(obj, "to_dict"): + return obj.to_dict() + if hasattr(obj, "hex"): + return obj.hex() + raise TypeError( + f"Object of type {obj.__class__.__name__} is not JSON serializable" + ) + + return safe_base64_encode(json.dumps(payment_payload, default=default)) + + +def decode_payment(encoded_payment: str) -> Dict[str, Any]: + """Decode a base64 encoded payment string.""" + return json.loads(safe_base64_decode(encoded_payment)) \ No newline at end of file diff --git a/python/x402/src/x402/exact.py b/python/x402/src/x402/exact.py index 4972b4612b..528df927c9 100644 --- a/python/x402/src/x402/exact.py +++ b/python/x402/src/x402/exact.py @@ -38,7 +38,7 @@ def prepare_payment_header( "value": payment_requirements.max_amount_required, "validAfter": valid_after, "validBefore": valid_before, - "nonce": nonce, + "nonce": nonce.hex(), }, }, } diff --git a/python/x402/src/x402/types.py b/python/x402/src/x402/types.py index 236417affd..7e95a3ff48 100644 --- a/python/x402/src/x402/types.py +++ b/python/x402/src/x402/types.py @@ -190,8 +190,78 @@ class SettleResponse(BaseModel): ) +# Deferred payment types +class DeferredEvmPayloadVoucher(BaseModel): + """Represents a deferred payment voucher for EVM chains""" + + id: str # Hex encoded 64 bytes (bytes32) + buyer: str # EVM address + seller: str # EVM address + value_aggregate: str # Total outstanding amount, monotonically increasing + asset: str # ERC-20 token address + timestamp: int # Unix timestamp + nonce: int # Incremented with each aggregation + escrow: str # Escrow contract address + chain_id: int # Network chain ID + expiry: int # Expiration timestamp + + model_config = ConfigDict( + alias_generator=to_camel, + populate_by_name=True, + from_attributes=True, + ) + + @field_validator("value_aggregate") + def validate_value_aggregate(cls, v): + try: + int(v) + except ValueError: + raise ValueError("value_aggregate must be an integer encoded as a string") + return v + + +class DeferredPaymentPayload(BaseModel): + """Payload for deferred payment scheme""" + + signature: str + voucher: DeferredEvmPayloadVoucher + + model_config = ConfigDict( + alias_generator=to_camel, + populate_by_name=True, + from_attributes=True, + ) + + +class DeferredPaymentRequirementsExtraNewVoucher(BaseModel): + """Extra data for creating a new deferred payment voucher""" + + type: Literal["new"] + voucher: dict # Contains only 'id' and 'escrow' fields + + model_config = ConfigDict( + alias_generator=to_camel, + populate_by_name=True, + from_attributes=True, + ) + + +class DeferredPaymentRequirementsExtraAggregationVoucher(BaseModel): + """Extra data for aggregating an existing deferred payment voucher""" + + type: Literal["aggregation"] + signature: str + voucher: DeferredEvmPayloadVoucher + + model_config = ConfigDict( + alias_generator=to_camel, + populate_by_name=True, + from_attributes=True, + ) + + # Union of payloads for each scheme -SchemePayloads = ExactPaymentPayload +SchemePayloads = Union[ExactPaymentPayload, DeferredPaymentPayload] class PaymentPayload(BaseModel): diff --git a/python/x402/tests/test_deferred.py b/python/x402/tests/test_deferred.py new file mode 100644 index 0000000000..447369fa11 --- /dev/null +++ b/python/x402/tests/test_deferred.py @@ -0,0 +1,272 @@ +import pytest +import time +from unittest.mock import patch +from eth_account import Account +from eth_utils import to_checksum_address + +from x402.deferred import ( + prepare_payment_header, + create_new_voucher, + aggregate_voucher, + sign_voucher, + verify_voucher, + sign_payment_header, + encode_payment, + decode_payment, + DEFERRED_SCHEME, + EXPIRY_TIME, +) +from x402.types import ( + PaymentRequirements, + DeferredEvmPayloadVoucher, +) + + +class TestDeferredPaymentScheme: + @pytest.fixture + def account(self): + """Create a test account.""" + return Account.from_key("0x" + "a" * 64) + + @pytest.fixture + def payment_requirements_new(self): + """Create payment requirements for a new voucher.""" + return PaymentRequirements( + scheme=DEFERRED_SCHEME, + network="base-sepolia", + max_amount_required="1000000000000000000", # 1 token + resource="/api/test", + description="Test API", + mime_type="application/json", + pay_to="0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + max_timeout_seconds=300, + asset="0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + extra={ + "type": "new", + "voucher": { + "id": "0x" + "1" * 64, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + } + } + ) + + @pytest.fixture + def existing_voucher(self, account): + """Create an existing voucher for aggregation tests.""" + return DeferredEvmPayloadVoucher( + id="0x" + "1" * 64, + buyer=account.address, + seller="0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + value_aggregate="1000000000000000000", + asset="0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + timestamp=int(time.time()) - 100, + nonce=1, + escrow="0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + chain_id=84532, + expiry=int(time.time()) + EXPIRY_TIME, + ) + + def test_create_new_voucher(self, account, payment_requirements_new): + """Test creating a new voucher.""" + voucher = create_new_voucher(account.address, payment_requirements_new) + + assert voucher.id == "0x" + "1" * 64 + assert voucher.buyer == to_checksum_address(account.address) + assert voucher.seller == to_checksum_address(payment_requirements_new.pay_to) + assert voucher.value_aggregate == payment_requirements_new.max_amount_required + assert voucher.asset == to_checksum_address(payment_requirements_new.asset) + assert voucher.nonce == 0 + assert voucher.escrow == to_checksum_address("0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27") + assert voucher.chain_id == 84532 # base-sepolia + assert voucher.timestamp > 0 + assert voucher.expiry > voucher.timestamp + + def test_sign_and_verify_voucher(self, account, existing_voucher): + """Test signing and verifying a voucher.""" + signature = sign_voucher(account, existing_voucher) + + assert signature.startswith("0x") + assert len(signature) == 132 # 0x + 130 hex chars + + # Verify with correct signer + assert verify_voucher(existing_voucher, signature, account.address) is True + + # Verify with wrong signer + wrong_account = Account.from_key("0x" + "b" * 64) + assert verify_voucher(existing_voucher, signature, wrong_account.address) is False + + def test_aggregate_voucher(self, account, existing_voucher): + """Test aggregating an existing voucher.""" + # Sign the existing voucher + signature = sign_voucher(account, existing_voucher) + + # Create payment requirements for aggregation + payment_requirements = PaymentRequirements( + scheme=DEFERRED_SCHEME, + network="base-sepolia", + max_amount_required="500000000000000000", # 0.5 token + resource="/api/test", + description="Test API", + mime_type="application/json", + pay_to=existing_voucher.seller, + max_timeout_seconds=300, + asset=existing_voucher.asset, + extra={ + "type": "aggregation", + "signature": signature, + "voucher": existing_voucher.model_dump(by_alias=True), + } + ) + + # Aggregate the voucher + aggregated = aggregate_voucher(account.address, payment_requirements) + + assert aggregated.id == existing_voucher.id + assert aggregated.buyer == to_checksum_address(account.address) + assert aggregated.seller == existing_voucher.seller + assert aggregated.value_aggregate == "1500000000000000000" # 1.5 tokens + assert aggregated.nonce == existing_voucher.nonce + 1 + assert aggregated.timestamp >= existing_voucher.timestamp + assert aggregated.expiry > aggregated.timestamp + + def test_aggregate_voucher_validation(self, account, existing_voucher): + """Test voucher aggregation validation.""" + signature = sign_voucher(account, existing_voucher) + + # Test with wrong seller + with pytest.raises(ValueError, match="Invalid voucher seller"): + payment_requirements = PaymentRequirements( + scheme=DEFERRED_SCHEME, + network="base-sepolia", + max_amount_required="500000000000000000", + resource="/api/test", + description="Test API", + mime_type="application/json", + pay_to="0x0000000000000000000000000000000000000001", # Wrong seller + max_timeout_seconds=300, + asset=existing_voucher.asset, + extra={ + "type": "aggregation", + "signature": signature, + "voucher": existing_voucher.model_dump(by_alias=True), + } + ) + aggregate_voucher(account.address, payment_requirements) + + # Test with wrong asset + with pytest.raises(ValueError, match="Invalid voucher asset"): + payment_requirements = PaymentRequirements( + scheme=DEFERRED_SCHEME, + network="base-sepolia", + max_amount_required="500000000000000000", + resource="/api/test", + description="Test API", + mime_type="application/json", + pay_to=existing_voucher.seller, + max_timeout_seconds=300, + asset="0x0000000000000000000000000000000000000002", # Wrong asset + extra={ + "type": "aggregation", + "signature": signature, + "voucher": existing_voucher.model_dump(by_alias=True), + } + ) + aggregate_voucher(account.address, payment_requirements) + + def test_prepare_payment_header(self, account, payment_requirements_new): + """Test preparing an unsigned payment header.""" + header = prepare_payment_header( + account.address, + 1, + payment_requirements_new + ) + + assert header["x402Version"] == 1 + assert header["scheme"] == DEFERRED_SCHEME + assert header["network"] == "base-sepolia" + assert header["payload"]["signature"] is None + assert header["payload"]["voucher"]["id"] == "0x" + "1" * 64 + assert header["payload"]["voucher"]["nonce"] == 0 + + def test_sign_payment_header(self, account, payment_requirements_new): + """Test signing a payment header.""" + header = prepare_payment_header( + account.address, + 1, + payment_requirements_new + ) + + encoded = sign_payment_header(account, payment_requirements_new, header) + + # Decode and verify + decoded = decode_payment(encoded) + assert decoded["x402Version"] == 1 + assert decoded["scheme"] == DEFERRED_SCHEME + assert decoded["payload"]["signature"].startswith("0x") + assert len(decoded["payload"]["signature"]) == 132 + + def test_expired_voucher(self, account): + """Test that expired vouchers are rejected.""" + # Create an expired voucher + expired_voucher = DeferredEvmPayloadVoucher( + id="0x" + "2" * 64, + buyer=account.address, + seller="0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + value_aggregate="1000000000000000000", + asset="0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + timestamp=int(time.time()) - 1000, + nonce=1, + escrow="0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + chain_id=84532, + expiry=int(time.time()) - 100, # Expired + ) + + signature = sign_voucher(account, expired_voucher) + + payment_requirements = PaymentRequirements( + scheme=DEFERRED_SCHEME, + network="base-sepolia", + max_amount_required="500000000000000000", + resource="/api/test", + description="Test API", + mime_type="application/json", + pay_to=expired_voucher.seller, + max_timeout_seconds=300, + asset=expired_voucher.asset, + extra={ + "type": "aggregation", + "signature": signature, + "voucher": expired_voucher.model_dump(by_alias=True), + } + ) + + with pytest.raises(ValueError, match="Voucher expired"): + aggregate_voucher(account.address, payment_requirements) + + def test_encode_decode_payment(self): + """Test encoding and decoding payment data.""" + payment_data = { + "x402Version": 1, + "scheme": DEFERRED_SCHEME, + "network": "base-sepolia", + "payload": { + "signature": "0x" + "a" * 130, + "voucher": { + "id": "0x" + "1" * 64, + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "1000000000000000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1234567890, + "nonce": 0, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1234567890 + EXPIRY_TIME, + } + } + } + + encoded = encode_payment(payment_data) + decoded = decode_payment(encoded) + + assert decoded == payment_data \ No newline at end of file From 8e7386ba3848ec00b9e12de0711f8e110e573017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 14 Aug 2025 17:18:42 -0300 Subject: [PATCH 040/116] chore: add signed voucher type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../packages/x402/src/types/verify/schemes/deferred.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index d7be33da39..7a1af17d9b 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -41,6 +41,12 @@ export const DeferredEvmPayloadVoucherSchema = z.object({ }); export type DeferredEvmPayloadVoucher = z.infer; +// x402DeferredEvmPayloadSignedVoucher +export const DeferredEvmPayloadSignedVoucherSchema = DeferredEvmPayloadVoucherSchema.extend({ + signature: z.string().regex(EvmSignatureRegex), +}); +export type DeferredEvmPayloadSignedVoucher = z.infer; + // x402DeferredEvmPayload export const DeferredEvmPayloadSchema = z.object({ signature: z.string().regex(EvmSignatureRegex), From 229ac4bbe6a3350efe5517b0899ed6907df6cc76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 20 Aug 2025 18:04:57 -0300 Subject: [PATCH 041/116] wip: merge gateway with facilitator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/facilitator/facilitator.ts | 25 +- .../src/schemes/deferred/evm/facilitator.ts | 124 +++++++- .../x402/src/schemes/deferred/evm/store.ts | 17 ++ .../x402/src/schemes/deferred/evm/verify.ts | 287 +++++++++++++----- .../x402/src/types/verify/schemes/deferred.ts | 24 +- .../x402/src/types/verify/x402Specs.ts | 8 + 6 files changed, 400 insertions(+), 85 deletions(-) create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/store.ts diff --git a/typescript/packages/x402/src/facilitator/facilitator.ts b/typescript/packages/x402/src/facilitator/facilitator.ts index 97082d9720..04a73dd9e4 100644 --- a/typescript/packages/x402/src/facilitator/facilitator.ts +++ b/typescript/packages/x402/src/facilitator/facilitator.ts @@ -10,6 +10,7 @@ import { ConnectedClient, Signer } from "../types/shared/wallet"; import { PaymentPayload, PaymentRequirements, + SchemeContext, SettleResponse, VerifyResponse, ExactEvmPayload, @@ -28,6 +29,7 @@ import { EXACT_SCHEME } from "../types/verify/schemes/exact"; * @param client - The public client used for blockchain interactions * @param payload - The signed payment payload containing transfer parameters and signature * @param paymentRequirements - The payment requirements that the payload must satisfy + * @param schemeContext - Scheme specific context for verification * @returns A ValidPaymentRequest indicating if the payment is valid and any invalidation reason */ export async function verify< @@ -38,6 +40,7 @@ export async function verify< client: ConnectedClient | Signer, payload: PaymentPayload, paymentRequirements: PaymentRequirements, + schemeContext?: SchemeContext, ): Promise { if (paymentRequirements.scheme == EXACT_SCHEME) { payload = ExactPaymentPayloadSchema.parse(payload); @@ -59,7 +62,14 @@ export async function verify< if (paymentRequirements.scheme == DEFERRRED_SCHEME) { payload = DeferredPaymentPayloadSchema.parse(payload); if (SupportedEVMNetworks.includes(paymentRequirements.network)) { - const valid = await verifyDeferred(client, payload, paymentRequirements); + if (!schemeContext) { + return { + isValid: false, + invalidReason: "missing_scheme_context", + payer: payload.payload.voucher.buyer, + }; + } + const valid = await verifyDeferred(client, payload, paymentRequirements, schemeContext); return valid; } else { return { @@ -87,12 +97,14 @@ export async function verify< * @param client - The signer wallet used for blockchain interactions * @param payload - The signed payment payload containing transfer parameters and signature * @param paymentRequirements - The payment requirements that the payload must satisfy + * @param schemeContext - Scheme specific context for verification * @returns A SettleResponse indicating if the payment is settled and any settlement reason */ export async function settle( client: Signer, payload: PaymentPayload, paymentRequirements: PaymentRequirements, + schemeContext?: SchemeContext, ): Promise { if (paymentRequirements.scheme == EXACT_SCHEME) { payload = ExactPaymentPayloadSchema.parse(payload); @@ -114,7 +126,16 @@ export async function settle( if (paymentRequirements.scheme == DEFERRRED_SCHEME) { payload = DeferredPaymentPayloadSchema.parse(payload); if (SupportedEVMNetworks.includes(paymentRequirements.network)) { - return settleDeferred(client, payload, paymentRequirements); + if (!schemeContext) { + return { + success: false, + errorReason: "missing_scheme_context", + transaction: "", + network: paymentRequirements.network, + payer: payload.payload.voucher.buyer, + }; + } + return settleDeferred(client, payload, paymentRequirements, schemeContext); } else { return { success: false, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 04ca9bbbd6..9e9ef0e2af 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -3,24 +3,41 @@ import { ConnectedClient, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, PaymentRequirements, + SchemeContext, SettleResponse, VerifyResponse, } from "../../../types/verify"; -import { DeferredPaymentPayloadSchema } from "../../../types/verify/schemes/deferred"; +import { + DeferredEvmPayloadVoucher, + DeferredEvmPayloadSignedVoucherSchema, + DeferredPaymentPayloadSchema, + DeferredPaymentRequirementsSchema, + DeferredSchemeContextSchema, +} from "../../../types/verify/schemes/deferred"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; -import { verifyPaymentRequirements, verifyVoucherSignature, verifyOnchainState } from "./verify"; +import { + verifyPaymentRequirements, + verifyVoucherSignature, + verifyOnchainState, + verifyVoucherContinuity, + verifyVoucherDuplicate, +} from "./verify"; +import { VoucherStore } from "./store"; /** * Verifies a payment payload against the required payment details * * This function performs several verification steps: - * - ✅ Validates the payment payload matches the payment requirements + * - ✅ Validates the payment payload satisfies the payment requirements + * - ✅ Validates the voucher structure is valid and continuity is maintained * - ✅ Validates the voucher signature is valid + * - ✅ Validates the previous voucher is available for aggregation vouchers * - ✅ Validates the onchain state allows the payment to be settled * * @param client - The public client used for blockchain interactions * @param paymentPayload - The signed payment payload containing transfer parameters and signature * @param paymentRequirements - The payment requirements that the payload must satisfy + * @param schemeContext - Scheme specific context for verification * @returns A ValidPaymentRequest indicating if the payment is valid and any invalidation reason */ export async function verify< @@ -31,25 +48,58 @@ export async function verify< client: ConnectedClient, paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements, + schemeContext: SchemeContext, ): Promise { - // Verify payload is a deferred payment payload - plus type assert to DeferredPaymentPayload paymentPayload = DeferredPaymentPayloadSchema.parse(paymentPayload); + paymentRequirements = DeferredPaymentRequirementsSchema.parse(paymentRequirements); + const { voucherStore } = DeferredSchemeContextSchema.parse(schemeContext.deferred); // Verify the payment payload matches the payment requirements - const requirementsResult = await verifyPaymentRequirements(paymentPayload, paymentRequirements); - if (requirementsResult) { + const requirementsResult = verifyPaymentRequirements(paymentPayload, paymentRequirements); + if (!requirementsResult.isValid) { return requirementsResult; } + // Verify voucher structure and continuity + const continuityResult = verifyVoucherContinuity(paymentPayload, paymentRequirements); + if (!continuityResult.isValid) { + return continuityResult; + } + // Verify voucher signature is valid const signatureResult = await verifyVoucherSignature(paymentPayload); - if (signatureResult) { + if (!signatureResult.isValid) { return signatureResult; } + // For aggregation vouchers, verify previous voucher availability + if (paymentRequirements.extra.type === "aggregation") { + const previousStoreVoucher = await voucherStore.getVoucher( + paymentRequirements.extra.voucher.id, + ); + if (!previousStoreVoucher) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_previous_voucher_not_found", + payer: paymentPayload.payload.voucher.buyer, + }; + } + const previousPaymentRequirementsVoucher = DeferredEvmPayloadSignedVoucherSchema.parse({ + ...paymentRequirements.extra.voucher, + signature: paymentRequirements.extra.signature, + }); + const duplicateResult = verifyVoucherDuplicate( + previousPaymentRequirementsVoucher, + previousStoreVoucher, + ); + if (!duplicateResult.isValid) { + return duplicateResult; + } + } + // Verify the onchain state allows the payment to be settled const onchainResult = await verifyOnchainState(client, paymentPayload, paymentRequirements); - if (onchainResult) { + if (!onchainResult.isValid) { return onchainResult; } @@ -69,18 +119,21 @@ export async function verify< * @param wallet - The facilitator wallet that will submit the transaction * @param paymentPayload - The signed payment payload containing the transfer parameters and signature * @param paymentRequirements - The original payment details that were used to create the payload + * @param schemeContext - Scheme specific context for verification * @returns A PaymentExecutionResponse containing the transaction status and hash */ export async function settle( wallet: SignerWallet, paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements, + schemeContext: SchemeContext, ): Promise { // Verify payload is a deferred payment payload - plus type assert to DeferredPaymentPayload paymentPayload = DeferredPaymentPayloadSchema.parse(paymentPayload); + const { voucherStore } = DeferredSchemeContextSchema.parse(schemeContext.deferred); // re-verify to ensure the payment is still valid - const valid = await verify(wallet, paymentPayload, paymentRequirements); + const valid = await verify(wallet, paymentPayload, paymentRequirements, schemeContext); if (!valid.isValid) { return { @@ -93,7 +146,35 @@ export async function settle( } const { voucher, signature } = paymentPayload.payload; + const response = await settleVoucher(wallet, voucher, signature, voucherStore); + return { + ...response, + network: paymentPayload.network, + }; +} + +/** + * Executes the voucher settlement transaction. The facilitator can invoke this function directly to settle a + * voucher in a deferred manner, outside of the x402 handshake. + * + * NOTE: Because of its deferred nature, payment requirements are not available when settling in deferred manner, + * in such cases, the payment is not re-verified. The facilitator is expected to have already performed verification + * at voucher creation time during the x402 handshake. The deferred escrow contract adds an additional layer of + * validation ensuring invalid payments cannot be settled. + * + * @param wallet - The facilitator wallet that will submit the transaction + * @param voucher - The voucher to settle + * @param signature - The signature of the voucher + * @param voucherStore - The voucher store to use for verification + * @returns A PaymentExecutionResponse containing the transaction status and hash + */ +export async function settleVoucher( + wallet: SignerWallet, + voucher: DeferredEvmPayloadVoucher, + signature: string, + voucherStore: VoucherStore, +): Promise { const tx = await wallet.writeContract({ address: voucher.escrow as Address, abi: deferredEscrowABI, @@ -123,15 +204,32 @@ export async function settle( success: false, errorReason: "invalid_transaction_state", transaction: tx, - network: paymentPayload.network, - payer: paymentPayload.payload.voucher.buyer, + payer: voucher.buyer, + }; + } + + try { + const success = await voucherStore.markVoucherSettled(voucher.id); + if (!success) { + return { + success: false, + errorReason: "invalid_deferred_evm_payload_voucher_could_not_settle_store", + transaction: tx, + payer: voucher.buyer, + }; + } + } catch { + return { + success: false, + errorReason: "invalid_deferred_evm_payload_voucher_could_not_settle_store", + transaction: tx, + payer: voucher.buyer, }; } return { success: true, transaction: tx, - network: paymentPayload.network, - payer: paymentPayload.payload.voucher.buyer, + payer: voucher.buyer, }; } diff --git a/typescript/packages/x402/src/schemes/deferred/evm/store.ts b/typescript/packages/x402/src/schemes/deferred/evm/store.ts new file mode 100644 index 0000000000..3886b9205c --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/store.ts @@ -0,0 +1,17 @@ +import { DeferredEvmPayloadSignedVoucher } from "../../../types/verify/schemes/deferred"; + +/** + * Voucher store interface for deferred EVM schemes + */ +export abstract class VoucherStore { + /** + * Get a voucher by its ID, returning the voucher with the highest nonce for that ID. + * Returns null if voucher id is not found. + */ + abstract getVoucher(voucherId: string): Promise; + + /** + * Mark a voucher as settled + */ + abstract markVoucherSettled(voucherId: string): Promise; +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index 2a30ce228a..5940a91464 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -1,5 +1,10 @@ import { Account, Chain, Address, Hex, Transport, getAddress } from "viem"; -import { DeferredPaymentPayload, DEFERRRED_SCHEME } from "../../../types/verify/schemes/deferred"; +import { + DeferredEvmPayloadSignedVoucher, + DeferredPaymentPayload, + DeferredPaymentRequirements, + DEFERRRED_SCHEME, +} from "../../../types/verify/schemes/deferred"; import { PaymentRequirements, VerifyResponse } from "../../../types"; import { getNetworkId } from "../../../shared"; import { verifyVoucher } from "./sign"; @@ -7,25 +12,17 @@ import { ConnectedClient } from "../../../types/shared/evm/wallet"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; /** - * Verifies the payment payload match the payment requirements - * - * - ✅ Verify scheme is deferred - * - ✅ Verify network matches payment requirements - * - ✅ Verify voucher value is enough to cover maxAmountRequired - * - ✅ Verify payTo is voucher seller - * - ✅ Verify voucher asset matches payment requirements - * - ✅ Validates the voucher chainId matches the chain specified in the payment requirements - * - ✅ Validates the voucher expiration and timestamp dates make sense + * Verifies the payment payload satisfies the payment requirements. * * @param paymentPayload - The payment payload to verify * @param paymentRequirements - The payment requirements to verify - * @returns The payment requirements if valid, otherwise an error object + * @returns Verification result */ -export async function verifyPaymentRequirements( +export function verifyPaymentRequirements( paymentPayload: DeferredPaymentPayload, - paymentRequirements: PaymentRequirements, -): Promise { - // Verify payload matches requirements: scheme + paymentRequirements: DeferredPaymentRequirements, +): VerifyResponse { + // scheme if (paymentPayload.scheme !== DEFERRRED_SCHEME) { return { isValid: false, @@ -39,7 +36,7 @@ export async function verifyPaymentRequirements( }; } - // Verify payload matches requirements: network + // network if (paymentPayload.network !== paymentRequirements.network) { return { isValid: false, @@ -47,91 +44,199 @@ export async function verifyPaymentRequirements( payer: paymentPayload.payload.voucher.buyer, }; } - - // Verify payload matches requirements: maxAmountRequired -- new vouchers - // value in voucher should be enough to cover paymentRequirements.maxAmountRequired - if (paymentRequirements.extra.type === "new") { - if ( - BigInt(paymentPayload.payload.voucher.valueAggregate) < - BigInt(paymentRequirements.maxAmountRequired) - ) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_value", - payer: paymentPayload.payload.voucher.buyer, - }; - } - } - - // Verify payload matches requirements: maxAmountRequired -- aggregate vouchers - // value in voucher should be enough to cover paymentRequirements.maxAmountRequired plus previous voucher value - if (paymentRequirements.extra.type === "aggregation") { - if ( - BigInt(paymentPayload.payload.voucher.valueAggregate) < - BigInt(paymentRequirements.maxAmountRequired) + - BigInt(paymentRequirements.extra.voucher.valueAggregate) - ) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_value", - payer: paymentPayload.payload.voucher.buyer, - }; - } + let chainId: number; + try { + chainId = getNetworkId(paymentRequirements.network); + } catch { + return { + isValid: false, + invalidReason: `invalid_network_unsupported`, + payer: paymentPayload.payload.voucher.buyer, + }; } - - // Verify payload matches requirements: payTo - if (getAddress(paymentPayload.payload.voucher.seller) !== getAddress(paymentRequirements.payTo)) { + if (chainId !== paymentPayload.payload.voucher.chainId) { return { isValid: false, - invalidReason: "invalid_deferred_evm_payload_recipient_mismatch", + invalidReason: `invalid_deferred_evm_payload_chain_id`, payer: paymentPayload.payload.voucher.buyer, }; } - // Verify payload matches requirements: asset - if (paymentPayload.payload.voucher.asset !== paymentRequirements.asset) { + // maxAmountRequired + const requiredVoucherValueAggregate = + paymentRequirements.extra.type === "new" + ? BigInt(paymentRequirements.maxAmountRequired) + : BigInt(paymentRequirements.maxAmountRequired) + + BigInt(paymentRequirements.extra.voucher.valueAggregate); + if (BigInt(paymentPayload.payload.voucher.valueAggregate) < requiredVoucherValueAggregate) { return { isValid: false, - invalidReason: "invalid_deferred_evm_payload_asset_mismatch", + invalidReason: "invalid_deferred_evm_payload_voucher_value", payer: paymentPayload.payload.voucher.buyer, }; } - //Validates the voucher chainId matches the chain specified in the payment requirements - let chainId: number; - try { - chainId = getNetworkId(paymentRequirements.network); - } catch { + // payTo + if (getAddress(paymentPayload.payload.voucher.seller) !== getAddress(paymentRequirements.payTo)) { return { isValid: false, - invalidReason: `invalid_network_unsupported`, + invalidReason: "invalid_deferred_evm_payload_recipient_mismatch", payer: paymentPayload.payload.voucher.buyer, }; } - if (chainId !== paymentPayload.payload.voucher.chainId) { + + // asset + if (paymentPayload.payload.voucher.asset !== paymentRequirements.asset) { return { isValid: false, - invalidReason: `invalid_deferred_evm_payload_chain_id`, + invalidReason: "invalid_deferred_evm_payload_asset_mismatch", payer: paymentPayload.payload.voucher.buyer, }; } - // Verify payload matches requirements: voucher expiration and timestamp + return { + isValid: true, + }; +} + +/** + * Verifies the voucher structrure is valid and continuity is maintained + * + * @param paymentPayload - The payment payload to verify + * @param paymentRequirements - The payment requirements to verify + * @returns Verification result + */ +export function verifyVoucherContinuity( + paymentPayload: DeferredPaymentPayload, + paymentRequirements: DeferredPaymentRequirements, +): VerifyResponse { + const voucher = paymentPayload.payload.voucher; + + // expiration const now = Math.floor(Date.now() / 1000); - if (paymentPayload.payload.voucher.expiry < now) { + if (voucher.expiry < now) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_expired", payer: paymentPayload.payload.voucher.buyer, }; } - if (paymentPayload.payload.voucher.timestamp > now) { + + // timestamp + if (voucher.timestamp > now) { return { isValid: false, - invalidReason: "invalid_deferred_evm_payload_timestamp", + invalidReason: "invalid_deferred_evm_payload_timestamp_too_early", payer: paymentPayload.payload.voucher.buyer, }; } + + // -- New voucher -- + if (paymentRequirements.extra.type === "new") { + if (voucher.nonce != 0) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_non_zero_nonce", + payer: paymentPayload.payload.voucher.buyer, + }; + } + if (BigInt(voucher.valueAggregate) == 0n) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_zero_value_aggregate", + payer: paymentPayload.payload.voucher.buyer, + }; + } + } + + // -- Aggregation voucher -- + if (paymentRequirements.extra.type === "aggregation") { + const previousVoucher = paymentRequirements.extra.voucher; + // id + if (voucher.id !== previousVoucher.id) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_id_mismatch", + payer: paymentPayload.payload.voucher.buyer, + }; + } + // buyer + if (voucher.buyer !== previousVoucher.buyer) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_buyer_mismatch", + payer: paymentPayload.payload.voucher.buyer, + }; + } + // seller + if (voucher.seller !== previousVoucher.seller) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_seller_mismatch", + payer: paymentPayload.payload.voucher.buyer, + }; + } + // valueAggregate + if (voucher.valueAggregate < previousVoucher.valueAggregate) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_value_aggregate_decreasing", + payer: paymentPayload.payload.voucher.buyer, + }; + } + // asset + if (voucher.asset !== previousVoucher.asset) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_asset_mismatch", + payer: paymentPayload.payload.voucher.buyer, + }; + } + // timestamp + if (voucher.timestamp < previousVoucher.timestamp) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_timestamp_decreasing", + payer: paymentPayload.payload.voucher.buyer, + }; + } + // nonce + if (voucher.nonce !== previousVoucher.nonce + 1) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_nonce_mismatch", + payer: paymentPayload.payload.voucher.buyer, + }; + } + // escrow + if (voucher.escrow !== previousVoucher.escrow) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_escrow_mismatch", + payer: paymentPayload.payload.voucher.buyer, + }; + } + // chainId + if (voucher.chainId !== previousVoucher.chainId) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_chain_id_mismatch", + payer: paymentPayload.payload.voucher.buyer, + }; + } + // expiry + if (voucher.expiry < previousVoucher.expiry) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_expiry_decreasing", + payer: paymentPayload.payload.voucher.buyer, + }; + } + } + + return { + isValid: true, + }; } /** @@ -141,11 +246,11 @@ export async function verifyPaymentRequirements( * - ✅ Verify the voucher signer is the buyer * * @param paymentPayload - The payment payload to verify - * @returns The payment requirements if valid, otherwise an error object + * @returns Verification result */ export async function verifyVoucherSignature( paymentPayload: DeferredPaymentPayload, -): Promise { +): Promise { const voucherSignatureIsValid = await verifyVoucher( paymentPayload.payload.voucher, paymentPayload.payload.signature as Hex, @@ -158,6 +263,46 @@ export async function verifyVoucherSignature( payer: paymentPayload.payload.voucher.buyer, }; } + + return { + isValid: true, + }; +} + +/** + * Verifies two vouchers are the same + * + * @param newVoucher - The new voucher to verify + * @param previousVoucher - The previous voucher to verify against + * @returns Verification result + */ +export function verifyVoucherDuplicate( + newVoucher: DeferredEvmPayloadSignedVoucher, + previousVoucher: DeferredEvmPayloadSignedVoucher, +): VerifyResponse { + if ( + newVoucher.id === previousVoucher.id && + newVoucher.buyer === previousVoucher.buyer && + newVoucher.seller === previousVoucher.seller && + newVoucher.valueAggregate === previousVoucher.valueAggregate && + newVoucher.asset === previousVoucher.asset && + newVoucher.timestamp === previousVoucher.timestamp && + newVoucher.nonce === previousVoucher.nonce && + newVoucher.escrow === previousVoucher.escrow && + newVoucher.chainId === previousVoucher.chainId && + newVoucher.expiry === previousVoucher.expiry && + newVoucher.signature === previousVoucher.signature + ) { + return { + isValid: true, + }; + } + + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: newVoucher.buyer, + }; } /** @@ -170,7 +315,7 @@ export async function verifyVoucherSignature( * @param client - The client to use for the onchain state verification * @param paymentPayload - The payment payload to verify * @param paymentRequirements - The payment requirements to verify - * @returns The payment requirements if valid, otherwise an error object + * @returns Verification result */ export async function verifyOnchainState< transport extends Transport, @@ -180,7 +325,7 @@ export async function verifyOnchainState< client: ConnectedClient, paymentPayload: DeferredPaymentPayload, paymentRequirements: PaymentRequirements, -): Promise { +): Promise { let chainId: number; try { chainId = getNetworkId(paymentRequirements.network); @@ -262,4 +407,8 @@ export async function verifyOnchainState< payer: paymentPayload.payload.voucher.buyer, }; } + + return { + isValid: true, + }; } diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 7a1af17d9b..f797e2224c 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -7,6 +7,7 @@ import { } from "../constants"; import { hasMaxLength, isInteger } from "../refiners"; import { BasePaymentPayloadSchema, BasePaymentRequirementsSchema } from "./base"; +import { VoucherStore } from "../../../schemes/deferred/evm/store"; export const DEFERRRED_SCHEME = "deferred"; @@ -21,9 +22,24 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_signature", "invalid_deferred_evm_payload_no_longer_valid", "invalid_deferred_evm_payload_voucher_expired", - "invalid_deferred_evm_payload_timestamp", + "invalid_deferred_evm_payload_timestamp_too_early", "invalid_deferred_evm_contract_call_failed_outstanding_amount", "invalid_deferred_evm_contract_call_failed_account", + "invalid_deferred_evm_payload_voucher_non_zero_nonce", + "invalid_deferred_evm_payload_voucher_id_mismatch", + "invalid_deferred_evm_payload_voucher_buyer_mismatch", + "invalid_deferred_evm_payload_voucher_seller_mismatch", + "invalid_deferred_evm_payload_voucher_asset_mismatch", + "invalid_deferred_evm_payload_voucher_escrow_mismatch", + "invalid_deferred_evm_payload_voucher_chain_id_mismatch", + "invalid_deferred_evm_payload_voucher_nonce_mismatch", + "invalid_deferred_evm_payload_voucher_value_aggregate_decreasing", + "invalid_deferred_evm_payload_voucher_timestamp_decreasing", + "invalid_deferred_evm_payload_voucher_expiry_decreasing", + "invalid_deferred_evm_payload_voucher_zero_value_aggregate", + "invalid_deferred_evm_payload_previous_voucher_not_found", + "invalid_deferred_evm_payload_voucher_not_duplicate", + "invalid_deferred_evm_payload_voucher_could_not_settle_store", ] as const; // x402DeferredEvmPayloadVoucher @@ -98,3 +114,9 @@ export const DeferredPaymentRequirementsSchema = BasePaymentRequirementsSchema.e ]), }); export type DeferredPaymentRequirements = z.infer; + +// x402DeferredSchemeContext +export const DeferredSchemeContextSchema = z.object({ + voucherStore: z.instanceof(VoucherStore), +}); +export type DeferredSchemeContext = z.infer; diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index a98e6620a6..e7c2911641 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -13,6 +13,7 @@ import { DeferredErrorReasons, DeferredPaymentPayloadSchema, DeferredPaymentRequirementsSchema, + DeferredSchemeContextSchema, UnsignedDeferredPaymentPayloadSchema, } from "./schemes/deferred"; import { x402Versions } from "./versions"; @@ -37,6 +38,7 @@ export const ErrorReasons = [ "unsupported_scheme", "unexpected_settle_error", "unexpected_verify_error", + "missing_scheme_context", ...ExactErrorReasons, ...DeferredErrorReasons, ] as const; @@ -188,3 +190,9 @@ export const SupportedPaymentKindsResponseSchema = z.object({ kinds: z.array(SupportedPaymentKindSchema), }); export type SupportedPaymentKindsResponse = z.infer; + +// x402SchemeContext +export const SchemeContextSchema = z.object({ + deferred: DeferredSchemeContextSchema.optional(), +}); +export type SchemeContext = z.infer; From 05992b2f7b525b5f90f00174ec92a8a8347b8e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 21 Aug 2025 15:22:56 -0300 Subject: [PATCH 042/116] feat: introduce previous gateway behavior into core deferred scheme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/facilitator.ts | 10 ++-- .../x402/src/schemes/deferred/evm/index.ts | 2 + .../x402/src/schemes/deferred/evm/store.ts | 36 ++++++++++++- .../packages/x402/src/shared/network.ts | 23 ++++++++- .../x402/src/types/verify/schemes/deferred.ts | 30 +++++++++++ .../packages/x402/src/verify/useDeferred.ts | 50 +++++++++++++++++++ .../x402/src/verify/useFacilitator.ts | 7 +-- 7 files changed, 148 insertions(+), 10 deletions(-) create mode 100644 typescript/packages/x402/src/verify/useDeferred.ts diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 9e9ef0e2af..d66e919b3f 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -159,9 +159,9 @@ export async function settle( * voucher in a deferred manner, outside of the x402 handshake. * * NOTE: Because of its deferred nature, payment requirements are not available when settling in deferred manner, - * in such cases, the payment is not re-verified. The facilitator is expected to have already performed verification - * at voucher creation time during the x402 handshake. The deferred escrow contract adds an additional layer of - * validation ensuring invalid payments cannot be settled. + * in such cases, the payment will not be re-verified before settlement. The facilitator is expected to have + * already performed verification at voucher creation time during the x402 handshake. The deferred escrow contract + * adds an additional layer of validation ensuring invalid payments cannot be settled. * * @param wallet - The facilitator wallet that will submit the transaction * @param voucher - The voucher to settle @@ -209,8 +209,8 @@ export async function settleVoucher; + /** + * Get the latest voucher by ( buyer, seller ) pair, returning the voucher with the highest nonce. + * Returns null if no voucher is found. + */ + abstract getVoucher( + buyer: string, + seller: string, + ): Promise; + + /** + * Get all vouchers by ( buyer, seller ) pair, returning the vouchers with the highest nonce. + * Must support pagination via limit and offset. + */ + abstract getVouchers( + buyer: string, + seller: string, + limit?: number, + offset?: number, + ): Promise>; + + /** + * Store a voucher. + * Must validate voucher signature. + */ + abstract storeVoucher( + voucher: DeferredEvmPayloadSignedVoucher, + signature: string, + ): Promise; + /** * Mark a voucher as settled */ - abstract markVoucherSettled(voucherId: string): Promise; + abstract markVoucherSettled(voucherId: string): Promise; } diff --git a/typescript/packages/x402/src/shared/network.ts b/typescript/packages/x402/src/shared/network.ts index e427b636b7..32b26d23aa 100644 --- a/typescript/packages/x402/src/shared/network.ts +++ b/typescript/packages/x402/src/shared/network.ts @@ -1,4 +1,9 @@ -import { EvmNetworkToChainId, Network, SvmNetworkToChainId } from "../types/shared"; +import { + EvmNetworkToChainId, + Network, + SvmNetworkToChainId, + ChainIdToEvmNetwork, +} from "../types/shared"; /** * Converts a network name to its corresponding chain ID @@ -16,3 +21,19 @@ export function getNetworkId(network: Network): number { } throw new Error(`Unsupported network: ${network}`); } + +/** + * Converts a chain ID to its corresponding network name + * + * @param chainId - The chain ID to convert to a network name + * @returns The network name for the specified chain ID + * @throws Error if the chain ID is not supported + */ +export function getNetworkName(chainId: number): Network { + if (ChainIdToEvmNetwork[chainId]) { + return ChainIdToEvmNetwork[chainId]; + } + + // TODO: Solana + throw new Error(`Unsupported chain ID: ${chainId}`); +} diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index f797e2224c..b33725c57a 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -120,3 +120,33 @@ export const DeferredSchemeContextSchema = z.object({ voucherStore: z.instanceof(VoucherStore), }); export type DeferredSchemeContext = z.infer; + +// x402DeferredErrorResponse +export const DeferredErrorResponseSchema = z.object({ + error: z.string(), + details: z.any().optional(), +}); +export type DeferredErrorResponse = z.infer; + +// x402DeferredVoucherResponse +export const DeferredVoucherResponseSchema = z.union([ + DeferredEvmPayloadSignedVoucherSchema, + DeferredErrorResponseSchema, +]); +export type DeferredVoucherResponse = z.infer; + +// x402DeferredVoucherHistoryResponse +export const DeferredVouchersResponseSchema = z.union([ + z.object({ + history: z.array(DeferredEvmPayloadSignedVoucherSchema), + count: z.number(), + buyer: z.string(), + seller: z.string(), + pagination: z.object({ + limit: z.number(), + offset: z.number(), + }), + }), + DeferredErrorResponseSchema, +]); +export type DeferredVouchersResponse = z.infer; diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts new file mode 100644 index 0000000000..9d52c3fc76 --- /dev/null +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -0,0 +1,50 @@ +import { DeferredErrorResponse, DeferredVouchersResponse, FacilitatorConfig } from "../types"; +import { DEFAULT_FACILITATOR_URL } from "./useFacilitator"; + +/** + * Creates a facilitator client for interacting with the X402 payment facilitator service + * + * @param facilitator - The facilitator config to use. If not provided, the default facilitator will be used. + * @returns An object containing verify and settle functions for interacting with the facilitator + */ +export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { + /** + * Fetches voucher history for a given buyer and seller + * + * @param buyer - The buyer address + * @param seller - The seller address + * @param limit - The maximum number of vouchers to return + * @param offset - The offset to start from + * @returns The voucher history + */ + async function getVouchers( + buyer: string, + seller: string, + limit?: number, + offset?: number, + ): Promise { + const url = facilitator?.url || DEFAULT_FACILITATOR_URL; + + const params = new URLSearchParams(); + if (limit !== undefined) params.append("limit", limit.toString()); + if (offset !== undefined) params.append("offset", offset.toString()); + const queryString = params.toString(); + + const response = await fetch( + `${url}/deferred/vouchers/history/${buyer}/${seller}${queryString ? `?${queryString}` : ""}`, + ); + const responseJson = await response.json(); + + if (response.status !== 200) { + const errorMessage = + (responseJson as DeferredErrorResponse).error || + `Failed to fetch voucher history: ${response.statusText}`; + throw new Error(errorMessage); + } + return responseJson as DeferredVouchersResponse; + } + + return { + getVouchers, + }; +} diff --git a/typescript/packages/x402/src/verify/useFacilitator.ts b/typescript/packages/x402/src/verify/useFacilitator.ts index 518f40947d..377b92d133 100644 --- a/typescript/packages/x402/src/verify/useFacilitator.ts +++ b/typescript/packages/x402/src/verify/useFacilitator.ts @@ -11,8 +11,9 @@ import { SettleResponse, VerifyResponse, } from "../types/verify"; +import { useDeferredFacilitator } from "./useDeferred"; -const DEFAULT_FACILITATOR_URL = "https://x402.org/facilitator"; +export const DEFAULT_FACILITATOR_URL = "https://x402.org/facilitator"; export type CreateHeaders = () => Promise<{ verify: Record; @@ -169,7 +170,7 @@ export function useFacilitator(facilitator?: FacilitatorConfig) { return data as ListDiscoveryResourcesResponse; } - return { verify, settle, supported, list }; + return { verify, settle, supported, list, deferred: useDeferredFacilitator(facilitator) }; } -export const { verify, settle, supported, list } = useFacilitator(); +export const { verify, settle, supported, list, deferred } = useFacilitator(); From 8b2f556c5d70174af0f9f2d52e7bba31dbbb5094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 21 Aug 2025 16:13:58 -0300 Subject: [PATCH 043/116] refactor: deferred verify steps to allow deferred settlement to run some of them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/facilitator.ts | 66 +++++----- .../x402/src/schemes/deferred/evm/verify.ts | 114 +++++++++++------- 2 files changed, 107 insertions(+), 73 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index d66e919b3f..ecc597b86d 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -9,7 +9,6 @@ import { } from "../../../types/verify"; import { DeferredEvmPayloadVoucher, - DeferredEvmPayloadSignedVoucherSchema, DeferredPaymentPayloadSchema, DeferredPaymentRequirementsSchema, DeferredSchemeContextSchema, @@ -20,7 +19,7 @@ import { verifyVoucherSignature, verifyOnchainState, verifyVoucherContinuity, - verifyVoucherDuplicate, + verifyPreviousVoucherAvailability, } from "./verify"; import { VoucherStore } from "./store"; @@ -67,38 +66,28 @@ export async function verify< } // Verify voucher signature is valid - const signatureResult = await verifyVoucherSignature(paymentPayload); + const signatureResult = await verifyVoucherSignature( + paymentPayload.payload.voucher, + paymentPayload.payload.signature, + ); if (!signatureResult.isValid) { return signatureResult; } - // For aggregation vouchers, verify previous voucher availability + // Verify previous voucher availability if (paymentRequirements.extra.type === "aggregation") { - const previousStoreVoucher = await voucherStore.getVoucher( - paymentRequirements.extra.voucher.id, + const previousVoucherResult = await verifyPreviousVoucherAvailability( + paymentRequirements.extra.voucher, + paymentRequirements.extra.signature, + voucherStore, ); - if (!previousStoreVoucher) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_previous_voucher_not_found", - payer: paymentPayload.payload.voucher.buyer, - }; - } - const previousPaymentRequirementsVoucher = DeferredEvmPayloadSignedVoucherSchema.parse({ - ...paymentRequirements.extra.voucher, - signature: paymentRequirements.extra.signature, - }); - const duplicateResult = verifyVoucherDuplicate( - previousPaymentRequirementsVoucher, - previousStoreVoucher, - ); - if (!duplicateResult.isValid) { - return duplicateResult; + if (!previousVoucherResult.isValid) { + return previousVoucherResult; } } // Verify the onchain state allows the payment to be settled - const onchainResult = await verifyOnchainState(client, paymentPayload, paymentRequirements); + const onchainResult = await verifyOnchainState(client, paymentPayload.payload.voucher); if (!onchainResult.isValid) { return onchainResult; } @@ -158,10 +147,9 @@ export async function settle( * Executes the voucher settlement transaction. The facilitator can invoke this function directly to settle a * voucher in a deferred manner, outside of the x402 handshake. * - * NOTE: Because of its deferred nature, payment requirements are not available when settling in deferred manner, - * in such cases, the payment will not be re-verified before settlement. The facilitator is expected to have - * already performed verification at voucher creation time during the x402 handshake. The deferred escrow contract - * adds an additional layer of validation ensuring invalid payments cannot be settled. + * NOTE: Because of its deferred nature, payment requirements are not available when settling in deferred manner + * which means some of the verification steps cannot be repeated before settlement. However, as long as the voucher + * has a matching signature and the on chain verification is successful the voucher can be settled. * * @param wallet - The facilitator wallet that will submit the transaction * @param voucher - The voucher to settle @@ -175,6 +163,28 @@ export async function settleVoucher { + // Verify the voucher signature + const signatureResult = await verifyVoucherSignature(voucher, signature); + if (!signatureResult.isValid) { + return { + success: false, + errorReason: signatureResult.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", + transaction: "", + payer: voucher.buyer, + }; + } + + // Verify the onchain state allows the payment to be settled + const valid = await verifyOnchainState(wallet, voucher); + if (!valid.isValid) { + return { + success: false, + errorReason: valid.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", + transaction: "", + payer: voucher.buyer, + }; + } + const tx = await wallet.writeContract({ address: voucher.escrow as Address, abi: deferredEscrowABI, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index 5940a91464..e6472e7805 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -1,15 +1,18 @@ import { Account, Chain, Address, Hex, Transport, getAddress } from "viem"; import { DeferredEvmPayloadSignedVoucher, + DeferredEvmPayloadSignedVoucherSchema, + DeferredEvmPayloadVoucher, DeferredPaymentPayload, DeferredPaymentRequirements, DEFERRRED_SCHEME, } from "../../../types/verify/schemes/deferred"; -import { PaymentRequirements, VerifyResponse } from "../../../types"; +import { VerifyResponse } from "../../../types"; import { getNetworkId } from "../../../shared"; import { verifyVoucher } from "./sign"; import { ConnectedClient } from "../../../types/shared/evm/wallet"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; +import { VoucherStore } from "./store"; /** * Verifies the payment payload satisfies the payment requirements. @@ -245,24 +248,62 @@ export function verifyVoucherContinuity( * - ✅ Verify the voucher signature is valid * - ✅ Verify the voucher signer is the buyer * - * @param paymentPayload - The payment payload to verify + * @param voucher - The voucher to verify + * @param signature - The signature of the voucher * @returns Verification result */ export async function verifyVoucherSignature( - paymentPayload: DeferredPaymentPayload, + voucher: DeferredEvmPayloadVoucher, + signature: string, ): Promise { const voucherSignatureIsValid = await verifyVoucher( - paymentPayload.payload.voucher, - paymentPayload.payload.signature as Hex, - paymentPayload.payload.voucher.buyer as Address, + voucher, + signature as Hex, + voucher.buyer as Address, ); if (!voucherSignatureIsValid) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_signature", - payer: paymentPayload.payload.voucher.buyer, + payer: voucher.buyer, + }; + } + + return { + isValid: true, + }; +} + +/** + * Verifies the previous voucher is available in the voucher store + * + * @param voucher - The voucher to verify + * @param signature - The signature of the voucher + * @param voucherStore - The voucher store to use for verification + * @returns Verification result + */ +export async function verifyPreviousVoucherAvailability( + voucher: DeferredEvmPayloadVoucher, + signature: string, + voucherStore: VoucherStore, +): Promise { + const storeVoucher = await voucherStore.getVoucher(voucher.id); + if (!storeVoucher) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_previous_voucher_not_found", + payer: voucher.buyer, }; } + const signedVoucher = DeferredEvmPayloadSignedVoucherSchema.parse({ + ...voucher, + signature, + }); + + const duplicateResult = verifyVoucherDuplicate(signedVoucher, storeVoucher); + if (!duplicateResult.isValid) { + return duplicateResult; + } return { isValid: true, @@ -270,7 +311,7 @@ export async function verifyVoucherSignature( } /** - * Verifies two vouchers are the same + * Verifies two vouchers are the same, down to the signature * * @param newVoucher - The new voucher to verify * @param previousVoucher - The previous voucher to verify against @@ -313,8 +354,7 @@ export function verifyVoucherDuplicate( * - ⌛ TODO: Simulate the transaction to ensure it will succeed * * @param client - The client to use for the onchain state verification - * @param paymentPayload - The payment payload to verify - * @param paymentRequirements - The payment requirements to verify + * @param voucher - The voucher to verify * @returns Verification result */ export async function verifyOnchainState< @@ -323,26 +363,14 @@ export async function verifyOnchainState< account extends Account | undefined, >( client: ConnectedClient, - paymentPayload: DeferredPaymentPayload, - paymentRequirements: PaymentRequirements, + voucher: DeferredEvmPayloadVoucher, ): Promise { - let chainId: number; - try { - chainId = getNetworkId(paymentRequirements.network); - } catch { - return { - isValid: false, - invalidReason: `invalid_network_unsupported`, - payer: paymentPayload.payload.voucher.buyer, - }; - } - // Verify the client is connected to the chain specified in the payment requirements - if (client.chain.id !== chainId) { + if (client.chain.id !== voucher.chainId) { return { isValid: false, invalidReason: "invalid_client_network", - payer: paymentPayload.payload.voucher.buyer, + payer: voucher.buyer, }; } @@ -351,21 +379,21 @@ export async function verifyOnchainState< let voucherOutstandingAmount: bigint; try { [voucherOutstandingAmount] = await client.readContract({ - address: paymentPayload.payload.voucher.escrow as Address, + address: voucher.escrow as Address, abi: deferredEscrowABI, functionName: "getOutstandingAndCollectableAmount", args: [ { - id: paymentPayload.payload.voucher.id as Hex, - buyer: paymentPayload.payload.voucher.buyer as Address, - seller: paymentPayload.payload.voucher.seller as Address, - valueAggregate: BigInt(paymentPayload.payload.voucher.valueAggregate), - asset: paymentPayload.payload.voucher.asset as Address, - timestamp: BigInt(paymentPayload.payload.voucher.timestamp), - nonce: BigInt(paymentPayload.payload.voucher.nonce), - escrow: paymentPayload.payload.voucher.escrow as Address, - chainId: BigInt(paymentPayload.payload.voucher.chainId), - expiry: BigInt(paymentPayload.payload.voucher.expiry), + id: voucher.id as Hex, + buyer: voucher.buyer as Address, + seller: voucher.seller as Address, + valueAggregate: BigInt(voucher.valueAggregate), + asset: voucher.asset as Address, + timestamp: BigInt(voucher.timestamp), + nonce: BigInt(voucher.nonce), + escrow: voucher.escrow as Address, + chainId: BigInt(voucher.chainId), + expiry: BigInt(voucher.expiry), }, ], }); @@ -373,7 +401,7 @@ export async function verifyOnchainState< return { isValid: false, invalidReason: "invalid_deferred_evm_contract_call_failed_outstanding_amount", - payer: paymentPayload.payload.voucher.buyer, + payer: voucher.buyer, }; } let buyerAccount: { @@ -383,28 +411,24 @@ export async function verifyOnchainState< }; try { buyerAccount = await client.readContract({ - address: paymentPayload.payload.voucher.escrow as Address, + address: voucher.escrow as Address, abi: deferredEscrowABI, functionName: "getAccount", - args: [ - paymentPayload.payload.voucher.buyer as Address, - paymentPayload.payload.voucher.seller as Address, - paymentPayload.payload.voucher.asset as Address, - ], + args: [voucher.buyer as Address, voucher.seller as Address, voucher.asset as Address], }); } catch (error) { console.log(error); return { isValid: false, invalidReason: "invalid_deferred_evm_contract_call_failed_account", - payer: paymentPayload.payload.voucher.buyer, + payer: voucher.buyer, }; } if (buyerAccount.balance < voucherOutstandingAmount) { return { isValid: false, invalidReason: "insufficient_funds", - payer: paymentPayload.payload.voucher.buyer, + payer: voucher.buyer, }; } From efeda4c04322fe2b16d9985915afe307fe3adc45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 22 Aug 2025 16:26:11 -0300 Subject: [PATCH 044/116] feat: implement full deferred api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/facilitator.ts | 56 +++-- .../x402/src/schemes/deferred/evm/store.ts | 51 +++- .../x402/src/schemes/deferred/evm/verify.ts | 2 +- .../x402/src/types/verify/schemes/deferred.ts | 4 +- .../x402/src/types/verify/x402Specs.ts | 4 +- .../packages/x402/src/verify/useDeferred.ts | 228 ++++++++++++++++-- 6 files changed, 290 insertions(+), 55 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index ecc597b86d..045610fa95 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -185,30 +185,40 @@ export async function settleVoucher; + abstract getVoucher(id: string, nonce?: number): Promise; /** - * Get the latest voucher by ( buyer, seller ) pair, returning the voucher with the highest nonce. - * Returns null if no voucher is found. + * Get a voucher series by their id (all nonces). + * Returns results sorted by nonce in descending order. + * Must support pagination via limit and offset. */ - abstract getVoucher( - buyer: string, - seller: string, - ): Promise; + abstract getVoucherSeries( + id: string, + pagination: { + limit?: number; + offset?: number; + }, + ): Promise>; /** - * Get all vouchers by ( buyer, seller ) pair, returning the vouchers with the highest nonce. + * Get all vouchers that match the provided query. + * If latest is true, returns only the highest nonce for each voucher id. * Must support pagination via limit and offset. */ abstract getVouchers( + query: { + buyer?: string; + seller?: string; + latest?: boolean; + }, + pagination: { + limit?: number; + offset?: number; + }, + ): Promise>; + + /** + * Get the latest available voucher for a given buyer and seller. + * An available voucher satisfies the following conditions: + * - The voucher matches the provided buyer and seller + * - The voucher has the highest nonce for that id + * - The voucher has the greatest timestamp for all ids with the same buyer and seller + * - The voucher is not currently locked by an ongoing request + */ + abstract getAvailableVoucher( buyer: string, seller: string, - limit?: number, - offset?: number, - ): Promise>; + ): Promise; /** * Store a voucher. diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index e6472e7805..8ec79bd925 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -287,7 +287,7 @@ export async function verifyPreviousVoucherAvailability( signature: string, voucherStore: VoucherStore, ): Promise { - const storeVoucher = await voucherStore.getVoucher(voucher.id); + const storeVoucher = await voucherStore.getVoucher(voucher.id, voucher.nonce); if (!storeVoucher) { return { isValid: false, diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index b33725c57a..50355d73c2 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -138,10 +138,8 @@ export type DeferredVoucherResponse = z.infer { + const url = facilitator?.url || DEFAULT_FACILITATOR_URL; + + const response = await fetch(`${url}/deferred/vouchers/${id}/${nonce}`); + const responseJson = (await response.json()) as DeferredVoucherResponse; + + if (response.status !== 200 || "error" in responseJson) { + const errorMessage = + (responseJson as DeferredErrorResponse).error || + `Failed to fetch voucher history: ${response.statusText}`; + throw new Error(errorMessage); + } + return responseJson; + } + + /** + * Fetches a voucher series by its id, sorted by nonce in descending order. + * + * @param id - The id of the voucher to fetch + * @param pagination - The pagination parameters + * @param pagination.limit - The maximum number of vouchers to return + * @param pagination.offset - The offset to start from + * @returns The vouchers + */ + async function getVoucherSeries( + id: string, + pagination: { + limit?: number; + offset?: number; + }, + ): Promise { + const url = facilitator?.url || DEFAULT_FACILITATOR_URL; + const { limit, offset } = pagination; + + const params = new URLSearchParams(); + if (limit !== undefined) params.append("limit", limit.toString()); + if (offset !== undefined) params.append("offset", offset.toString()); + const queryString = params.toString(); + + const response = await fetch( + `${url}/deferred/vouchers/${id}${queryString ? `?${queryString}` : ""}`, + ); + const responseJson = (await response.json()) as DeferredVouchersResponse; + + if (response.status !== 200 || "error" in responseJson) { + const errorMessage = + (responseJson as DeferredErrorResponse).error || + `Failed to fetch voucher history: ${response.statusText}`; + throw new Error(errorMessage); + } + return responseJson; + } + + /** + * Fetches the latest voucher for a given buyer and seller + * + * @param query - The query parameters + * @param query.buyer - The buyer address + * @param query.seller - The seller address + * @param query.latest - Whether to return the latest voucher for each id + * @param pagination - The pagination parameters + * @param pagination.limit - The maximum number of vouchers to return + * @param pagination.offset - The offset to start from + * @returns The vouchers */ async function getVouchers( - buyer: string, - seller: string, - limit?: number, - offset?: number, + query: { + buyer: string; + seller: string; + latest?: boolean; + }, + pagination: { + limit?: number; + offset?: number; + }, ): Promise { const url = facilitator?.url || DEFAULT_FACILITATOR_URL; + const { buyer, seller, latest } = query; + const { limit, offset } = pagination; const params = new URLSearchParams(); if (limit !== undefined) params.append("limit", limit.toString()); if (offset !== undefined) params.append("offset", offset.toString()); + if (latest !== undefined) params.append("latest", latest.toString()); + if (buyer !== undefined) params.append("buyer", buyer); + if (seller !== undefined) params.append("seller", seller); const queryString = params.toString(); const response = await fetch( - `${url}/deferred/vouchers/history/${buyer}/${seller}${queryString ? `?${queryString}` : ""}`, + `${url}/deferred/vouchers?${queryString ? `?${queryString}` : ""}`, ); + const responseJson = (await response.json()) as DeferredVouchersResponse; + + if (response.status !== 200 || "error" in responseJson) { + const errorMessage = + (responseJson as DeferredErrorResponse).error || + `Failed to fetch voucher history: ${response.statusText}`; + throw new Error(errorMessage); + } + return responseJson; + } + + /** + * Fetches the latest available voucher for a given buyer and seller + * + * @param buyer - The buyer address + * @param seller - The seller address + * @returns The voucher + */ + async function getAvailableVoucher( + buyer: string, + seller: string, + ): Promise { + const url = facilitator?.url || DEFAULT_FACILITATOR_URL; + + const response = await fetch(`${url}/deferred/vouchers/available/${buyer}/${seller}`); + const responseJson = (await response.json()) as DeferredVoucherResponse; + + // If the voucher is not found we don't throw, clients should just create a new voucher from scratch + if (response.status === 404) { + return { + error: "voucher_not_found", + }; + } + + if (response.status !== 200 || "error" in responseJson) { + const errorMessage = + (responseJson as DeferredErrorResponse).error || + `Failed to fetch available voucher: ${response.statusText}`; + throw new Error(errorMessage); + } + + return responseJson; + } + + /** + * Stores a voucher in the facilitator + * + * @param voucher - The signedvoucher to store + * @returns The result of the store operation + */ + async function storeVoucher( + voucher: DeferredEvmPayloadSignedVoucher, + ): Promise { + const url = facilitator?.url || DEFAULT_FACILITATOR_URL; + + const response = await fetch(`${url}/deferred/vouchers`, { + method: "POST", + body: JSON.stringify(voucher), + headers: { + "Content-Type": "application/json", + }, + }); + const responseJson = await response.json(); + + if (response.status !== 201) { + const errorMessage = + (responseJson as DeferredErrorResponse).error || + `Failed to store voucher: ${response.statusText}`; + throw new Error(errorMessage); + } + + return responseJson as DeferredVoucherResponse; + } + + /** + * Verifies a voucher signature and onchain state. + * + * @param id - The id of the voucher to verify + * @param nonce - The nonce of the voucher to verify + * @returns The verification result + */ + async function verifyVoucher(id: string, nonce: number): Promise { + const url = facilitator?.url || DEFAULT_FACILITATOR_URL; + + const response = await fetch(`${url}/deferred/vouchers/${id}/${nonce}/verify`, { + method: "POST", + }); const responseJson = await response.json(); if (response.status !== 200) { const errorMessage = (responseJson as DeferredErrorResponse).error || - `Failed to fetch voucher history: ${response.statusText}`; + `Failed to verify voucher: ${response.statusText}`; throw new Error(errorMessage); } - return responseJson as DeferredVouchersResponse; + + return responseJson as VerifyResponse; + } + + /** + * Settles a voucher by its id and nonce. + * + * @param id - The id of the voucher to settle + * @param nonce - The nonce of the voucher to settle + * @returns The settlement result + */ + async function settleVoucher(id: string, nonce: number): Promise { + const url = facilitator?.url || DEFAULT_FACILITATOR_URL; + + const response = await fetch(`${url}/deferred/vouchers/${id}/${nonce}/settle`, { + method: "POST", + }); + const responseJson = await response.json(); + + if (response.status !== 200) { + const errorMessage = + (responseJson as DeferredErrorResponse).error || + `Failed to settle voucher: ${response.statusText}`; + throw new Error(errorMessage); + } + + return responseJson as SettleResponse; } return { + getVoucher, getVouchers, + getVoucherSeries, + getAvailableVoucher, + storeVoucher, + verifyVoucher, + settleVoucher, }; } From 206c115917c1c4963799807178dd14e117c16c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 22 Aug 2025 18:07:25 -0300 Subject: [PATCH 045/116] docs: minor comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../packages/x402/src/schemes/deferred/evm/facilitator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 045610fa95..eb5727e8e5 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -149,7 +149,7 @@ export async function settle( * * NOTE: Because of its deferred nature, payment requirements are not available when settling in deferred manner * which means some of the verification steps cannot be repeated before settlement. However, as long as the voucher - * has a matching signature and the on chain verification is successful the voucher can be settled. + * has a matching signature and the on chain verification is successful the voucher should be safe to settle. * * @param wallet - The facilitator wallet that will submit the transaction * @param voucher - The voucher to settle From f9c69a984163a4c02724cd75986b58fa1045a550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 25 Aug 2025 18:02:41 -0300 Subject: [PATCH 046/116] feat: complete gateway migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/schemes/deferred/evm/client.ts | 16 +- .../src/schemes/deferred/evm/facilitator.ts | 13 +- .../x402/src/schemes/deferred/evm/store.ts | 165 +++++++++++++++--- .../x402/src/schemes/deferred/evm/verify.ts | 20 +-- .../x402/src/types/verify/constants.ts | 1 + .../x402/src/types/verify/schemes/deferred.ts | 32 +++- 6 files changed, 203 insertions(+), 44 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index 9494a3f03b..3cfda51065 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -1,4 +1,4 @@ -import { Address, Chain, Hex, LocalAccount, Transport } from "viem"; +import { Address, Chain, getAddress, Hex, LocalAccount, Transport } from "viem"; import { getNetworkId } from "../../../shared/network"; import { isSignerWallet, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, PaymentRequirements, UnsignedPaymentPayload } from "../../../types/verify"; @@ -63,14 +63,14 @@ export function createNewVoucher( ); return { - id: extra.voucher.id, - buyer: buyer, - seller: paymentRequirements.payTo, + id: extra.voucher.id.toLowerCase(), + buyer: getAddress(buyer), + seller: getAddress(paymentRequirements.payTo), valueAggregate: paymentRequirements.maxAmountRequired, - asset: paymentRequirements.asset, + asset: getAddress(paymentRequirements.asset), timestamp: Math.floor(Date.now() / 1000), nonce: 0, - escrow: extra.voucher.escrow, + escrow: getAddress(extra.voucher.escrow), chainId: getNetworkId(paymentRequirements.network), expiry: Math.floor(Date.now() / 1000) + EXPIRY_TIME, }; @@ -95,10 +95,10 @@ export async function aggregateVoucher( const now = Math.floor(Date.now() / 1000); // verify previous voucher matches payment requirements - if (paymentRequirements.payTo !== seller) { + if (getAddress(paymentRequirements.payTo) !== getAddress(seller)) { throw new Error("Invalid voucher seller"); } - if (paymentRequirements.asset !== asset) { + if (getAddress(paymentRequirements.asset) !== getAddress(asset)) { throw new Error("Invalid voucher asset"); } if (getNetworkId(paymentRequirements.network) !== chainId) { diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index eb5727e8e5..41569bf0c6 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -1,4 +1,4 @@ -import { Account, Address, Chain, Transport, Hex } from "viem"; +import { Account, Address, Chain, Transport, Hex, parseEventLogs } from "viem"; import { ConnectedClient, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, @@ -228,8 +228,15 @@ export async function settleVoucher 0 ? BigInt(logs[0].args.amount) : BigInt(0); + try { - const actionResult = await voucherStore.markVoucherSettled(voucher.id); + const actionResult = await voucherStore.settleVoucher(voucher, tx, collectedAmount); if (!actionResult.success) { return { success: false, @@ -241,7 +248,7 @@ export async function settleVoucher; /** - * Get a voucher series by their id (all nonces). - * Returns results sorted by nonce in descending order. - * Must support pagination via limit and offset. + * Retrieve all vouchers in a series by id + * + * @param id - The voucher series identifier + * @param pagination - Pagination options + * @returns Array of vouchers sorted by nonce (descending) + * + * Implementation requirements: + * - Results must be sorted by nonce in descending order (newest first) + * - Must support pagination with limit/offset + * - Should return empty array if series doesn't exist + * - Default limit should be reasonable (e.g., 100) if not specified + * + * @example + * ```typescript + * // Get first 10 vouchers in series + * const vouchers = await store.getVoucherSeries("0x123...", { limit: 10, offset: 0 }); + * ``` */ abstract getVoucherSeries( id: string, @@ -33,9 +70,36 @@ export abstract class VoucherStore { ): Promise>; /** - * Get all vouchers that match the provided query. - * If latest is true, returns only the highest nonce for each voucher id. - * Must support pagination via limit and offset. + * Query vouchers with filtering and pagination + * + * @param query - Filter criteria + * @param pagination - Pagination options + * @returns Array of vouchers matching the criteria + * + * Query Options: + * - buyer: Filter by buyer's address + * - seller: Filter by seller's address + * - latest: If true, return only the highest nonce voucher per series + * + * Behavior: + * - When latest=true: returns one voucher per series (the one with highest nonce) + * - When latest=false: returns all vouchers matching buyer/seller criteria + * - Results should be sorted by nonce descending, then by timestamp descending + * + * @example + * ```typescript + * // Get all latest vouchers for a buyer + * const latest = await store.getVouchers( + * { buyer: "0x123...", latest: true }, + * { limit: 50 } + * ); + * + * // Get all historical vouchers for a pair + * const history = await store.getVouchers( + * { buyer: "0x123...", seller: "0x456...", latest: false }, + * { limit: 100, offset: 0 } + * ); + * ``` */ abstract getVouchers( query: { @@ -50,12 +114,25 @@ export abstract class VoucherStore { ): Promise>; /** - * Get the latest available voucher for a given buyer and seller. - * An available voucher satisfies the following conditions: - * - The voucher matches the provided buyer and seller - * - The voucher has the highest nonce for that id - * - The voucher has the greatest timestamp for all ids with the same buyer and seller - * - The voucher is not currently locked by an ongoing request + * Get the "latest available" voucher for a given buyer and seller. + * + * @param buyer - The buyer's address + * @param seller - The seller's address + * @returns The available voucher or null if none available + * + * The voucher to return must follow the following selection criteria: + * 1. Voucher matches the provided buyer and seller addresses + * 2. Voucher has the highest nonce for its series + * 3. Among multiple matching series, select the one with the most recent timestamp + * + * @example + * ```typescript + * // Get the latest available voucher for a given buyer and seller + * const voucher = await store.getAvailableVoucher("0xbuyer...", "0xseller..."); + * if (voucher) { + * // Process payment... + * } + * ``` */ abstract getAvailableVoucher( buyer: string, @@ -63,8 +140,21 @@ export abstract class VoucherStore { ): Promise; /** - * Store a voucher. - * Must validate voucher signature. + * Store a new voucher in the system + * + * @param voucher - The signed voucher to store + * @param signature - The cryptographic signature + * @returns Result indicating success/failure + * + * @example + * ```typescript + * const result = await store.storeVoucher(signedVoucher, signature); + * if (result.success) { + * console.log("Voucher stored successfully"); + * } else { + * console.error("Failed to store voucher:", result.error); + * } + * ``` */ abstract storeVoucher( voucher: DeferredEvmPayloadSignedVoucher, @@ -72,7 +162,40 @@ export abstract class VoucherStore { ): Promise; /** - * Mark a voucher as settled + * Record the settlement of a voucher on-chain + * + * @param voucher - The voucher that was settled + * @param txHash - The transaction hash of the settlement + * @param amount - The actual amount collected (as determined by on-chain logic) + * @returns Result indicating success/failure + * + * @example + * ```typescript + * // Record settlement + * const result = await store.settleVoucher(voucher, "0xabc123...", 1000000n); + * ``` */ - abstract markVoucherSettled(voucherId: string): Promise; + abstract settleVoucher( + voucher: DeferredEvmPayloadVoucher, + txHash: string, + amount: bigint, + ): Promise; + + /** + * Get the collections for a voucher + * + * @param id - The voucher id + * @param nonce - The voucher nonce + * @returns The collections for the voucher + * + * @example + * ```typescript + * // Get the collections for a voucher + * const collections = await store.getVoucherCollections("0x123...", 5); + * ``` + */ + abstract getVoucherCollections( + id: string, + nonce: number, + ): Promise>; } diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index 8ec79bd925..fd7cbed637 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -156,7 +156,7 @@ export function verifyVoucherContinuity( if (paymentRequirements.extra.type === "aggregation") { const previousVoucher = paymentRequirements.extra.voucher; // id - if (voucher.id !== previousVoucher.id) { + if (voucher.id.toLowerCase() !== previousVoucher.id.toLowerCase()) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_id_mismatch", @@ -164,7 +164,7 @@ export function verifyVoucherContinuity( }; } // buyer - if (voucher.buyer !== previousVoucher.buyer) { + if (getAddress(voucher.buyer) !== getAddress(previousVoucher.buyer)) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_buyer_mismatch", @@ -172,7 +172,7 @@ export function verifyVoucherContinuity( }; } // seller - if (voucher.seller !== previousVoucher.seller) { + if (getAddress(voucher.seller) !== getAddress(previousVoucher.seller)) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_seller_mismatch", @@ -188,7 +188,7 @@ export function verifyVoucherContinuity( }; } // asset - if (voucher.asset !== previousVoucher.asset) { + if (getAddress(voucher.asset) !== getAddress(previousVoucher.asset)) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_asset_mismatch", @@ -212,7 +212,7 @@ export function verifyVoucherContinuity( }; } // escrow - if (voucher.escrow !== previousVoucher.escrow) { + if (getAddress(voucher.escrow) !== getAddress(previousVoucher.escrow)) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_escrow_mismatch", @@ -322,14 +322,14 @@ export function verifyVoucherDuplicate( previousVoucher: DeferredEvmPayloadSignedVoucher, ): VerifyResponse { if ( - newVoucher.id === previousVoucher.id && - newVoucher.buyer === previousVoucher.buyer && - newVoucher.seller === previousVoucher.seller && + newVoucher.id.toLowerCase() === previousVoucher.id.toLowerCase() && + getAddress(newVoucher.buyer) === getAddress(previousVoucher.buyer) && + getAddress(newVoucher.seller) === getAddress(previousVoucher.seller) && newVoucher.valueAggregate === previousVoucher.valueAggregate && - newVoucher.asset === previousVoucher.asset && + getAddress(newVoucher.asset) === getAddress(previousVoucher.asset) && newVoucher.timestamp === previousVoucher.timestamp && newVoucher.nonce === previousVoucher.nonce && - newVoucher.escrow === previousVoucher.escrow && + getAddress(newVoucher.escrow) === getAddress(previousVoucher.escrow) && newVoucher.chainId === previousVoucher.chainId && newVoucher.expiry === previousVoucher.expiry && newVoucher.signature === previousVoucher.signature diff --git a/typescript/packages/x402/src/types/verify/constants.ts b/typescript/packages/x402/src/types/verify/constants.ts index d39821e6db..45776da315 100644 --- a/typescript/packages/x402/src/types/verify/constants.ts +++ b/typescript/packages/x402/src/types/verify/constants.ts @@ -4,3 +4,4 @@ export const EvmAddressRegex = /^0x[0-9a-fA-F]{40}$/; export const MixedAddressRegex = /^0x[a-fA-F0-9]{40}|[A-Za-z0-9][A-Za-z0-9-]{0,34}[A-Za-z0-9]$/; export const HexEncoded64ByteRegex = /^0x[0-9a-fA-F]{64}$/; export const EvmSignatureRegex = /^0x[0-9a-fA-F]+$/; // Flexible hex signature validation +export const EvmTransactionHashRegex = /^0x[0-9a-fA-F]{64}$/; diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 50355d73c2..0a5e3bbdc0 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -4,6 +4,7 @@ import { EvmSignatureRegex, HexEncoded64ByteRegex, EvmMaxAtomicUnits, + EvmTransactionHashRegex, } from "../constants"; import { hasMaxLength, isInteger } from "../refiners"; import { BasePaymentPayloadSchema, BasePaymentRequirementsSchema } from "./base"; @@ -40,6 +41,7 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_previous_voucher_not_found", "invalid_deferred_evm_payload_voucher_not_duplicate", "invalid_deferred_evm_payload_voucher_could_not_settle_store", + "invalid_deferred_evm_payload_voucher_error_settling_store", ] as const; // x402DeferredEvmPayloadVoucher @@ -63,6 +65,18 @@ export const DeferredEvmPayloadSignedVoucherSchema = DeferredEvmPayloadVoucherSc }); export type DeferredEvmPayloadSignedVoucher = z.infer; +// x402DeferredVoucherCollection +export const DeferredVoucherCollectionSchema = z.object({ + voucherId: z.string().regex(HexEncoded64ByteRegex), + voucherNonce: z.number().int().nonnegative(), + transactionHash: z.string().regex(EvmTransactionHashRegex), + collectedAmount: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + asset: z.string().regex(EvmAddressRegex), + chainId: z.number().int().nonnegative(), + collectedAt: z.number().int().nonnegative(), +}); +export type DeferredVoucherCollection = z.infer; + // x402DeferredEvmPayload export const DeferredEvmPayloadSchema = z.object({ signature: z.string().regex(EvmSignatureRegex), @@ -135,10 +149,10 @@ export const DeferredVoucherResponseSchema = z.union([ ]); export type DeferredVoucherResponse = z.infer; -// x402DeferredVoucherHistoryResponse +// x402DeferredVouchersResponse export const DeferredVouchersResponseSchema = z.union([ z.object({ - data: z.array(DeferredEvmPayloadSignedVoucherSchema), + data: z.array(DeferredVoucherResponseSchema), count: z.number(), pagination: z.object({ limit: z.number(), @@ -148,3 +162,17 @@ export const DeferredVouchersResponseSchema = z.union([ DeferredErrorResponseSchema, ]); export type DeferredVouchersResponse = z.infer; + +// x402DeferredVoucherCollectionResponse +export const DeferredVoucherCollectionResponseSchema = z.object({ + voucherId: z.string(), + voucherNonce: z.number(), + transactionHash: z.string(), + collectedAmount: z.string(), + asset: z.string(), + chainId: z.number(), + timestamp: z.number(), +}); +export type DeferredVoucherCollectionResponse = z.infer< + typeof DeferredVoucherCollectionResponseSchema +>; From 6ecab71b1b12741298bdc22756318ea9a38f8d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 26 Aug 2025 10:59:35 -0300 Subject: [PATCH 047/116] chore: fix network getter name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/shared/network.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/packages/x402/src/shared/network.ts b/typescript/packages/x402/src/shared/network.ts index 32b26d23aa..355fc51160 100644 --- a/typescript/packages/x402/src/shared/network.ts +++ b/typescript/packages/x402/src/shared/network.ts @@ -2,7 +2,7 @@ import { EvmNetworkToChainId, Network, SvmNetworkToChainId, - ChainIdToEvmNetwork, + ChainIdToNetwork, } from "../types/shared"; /** @@ -30,8 +30,8 @@ export function getNetworkId(network: Network): number { * @throws Error if the chain ID is not supported */ export function getNetworkName(chainId: number): Network { - if (ChainIdToEvmNetwork[chainId]) { - return ChainIdToEvmNetwork[chainId]; + if (ChainIdToNetwork[chainId]) { + return ChainIdToNetwork[chainId]; } // TODO: Solana From 2642375534759327ded80fa098b10d773f9951ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 26 Aug 2025 11:14:50 -0300 Subject: [PATCH 048/116] test: fix deferred tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/client.test.ts | 2 +- .../src/schemes/deferred/evm/verify.test.ts | 122 +++++++----------- .../x402/src/types/verify/schemes/deferred.ts | 2 +- 3 files changed, 50 insertions(+), 76 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts index a226713a23..6cb8930c05 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -25,7 +25,7 @@ const buyer = createSigner( ); const buyerAddress = buyer.account.address; const sellerAddress = "0x1234567890123456789012345678901234567890"; -const escrowAddress = "0xffffff12345678901234567890123456789fffff"; +const escrowAddress = "0xffFfFf12345678901234567890123456789fffFF"; const assetAddress = "0x1111111111111111111111111111111111111111"; const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts index 5652237017..ad9773f755 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts @@ -1,6 +1,10 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { PaymentRequirements } from "../../../types"; -import { DeferredPaymentPayload, DEFERRRED_SCHEME } from "../../../types/verify/schemes/deferred"; +import { + DeferredPaymentPayload, + DeferredPaymentRequirements, + DEFERRRED_SCHEME, +} from "../../../types/verify/schemes/deferred"; import { verifyPaymentRequirements, verifyVoucherSignature, verifyOnchainState } from "./verify"; import { ConnectedClient } from "../../../types/shared/evm/wallet"; import { verifyVoucher } from "./sign"; @@ -77,7 +81,7 @@ describe("verifyPaymentRequirements", () => { it("should return undefined for valid payment requirements with new voucher", async () => { const result = await verifyPaymentRequirements(mockPaymentPayload, mockPaymentRequirements); - expect(result).toBeUndefined(); + expect(result).toEqual({ isValid: true }); }); it("should return undefined for valid payment requirements with aggregation voucher", async () => { @@ -94,7 +98,7 @@ describe("verifyPaymentRequirements", () => { }, }; const result = await verifyPaymentRequirements(mockPaymentPayload, aggregationRequirements); - expect(result).toBeUndefined(); + expect(result).toEqual({ isValid: true }); }); it("should return error if payload scheme is not deferred", async () => { @@ -114,7 +118,10 @@ describe("verifyPaymentRequirements", () => { ...mockPaymentRequirements, scheme: "immediate", } as unknown as PaymentRequirements; - const result = await verifyPaymentRequirements(mockPaymentPayload, invalidRequirements); + const result = verifyPaymentRequirements( + mockPaymentPayload, + invalidRequirements as DeferredPaymentRequirements, + ); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_requirements_scheme", @@ -249,11 +256,8 @@ describe("verifyPaymentRequirements", () => { }, }; const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); - expect(result).toEqual({ - isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_expired", - payer: buyerAddress, - }); + // verifyPaymentRequirements doesn't check expiry, it returns isValid: true + expect(result).toEqual({ isValid: true }); }); it("should return error if voucher timestamp is in the future", async () => { @@ -269,11 +273,8 @@ describe("verifyPaymentRequirements", () => { }, }; const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); - expect(result).toEqual({ - isValid: false, - invalidReason: "invalid_deferred_evm_payload_timestamp", - payer: buyerAddress, - }); + // verifyPaymentRequirements doesn't check timestamp, it returns isValid: true + expect(result).toEqual({ isValid: true }); }); }); @@ -309,8 +310,11 @@ describe("verifyVoucherSignature", () => { it("should return undefined for valid voucher signature", async () => { vi.mocked(verifyVoucher).mockResolvedValue(true); - const result = await verifyVoucherSignature(mockPaymentPayload); - expect(result).toBeUndefined(); + const result = await verifyVoucherSignature( + mockPaymentPayload.payload.voucher, + mockPaymentPayload.payload.signature, + ); + expect(result).toEqual({ isValid: true }); expect(vi.mocked(verifyVoucher)).toHaveBeenCalledWith( mockPaymentPayload.payload.voucher, voucherSignature, @@ -320,7 +324,10 @@ describe("verifyVoucherSignature", () => { it("should return error for invalid voucher signature", async () => { vi.mocked(verifyVoucher).mockResolvedValue(false); - const result = await verifyVoucherSignature(mockPaymentPayload); + const result = await verifyVoucherSignature( + mockPaymentPayload.payload.voucher, + mockPaymentPayload.payload.signature, + ); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_payload_signature", @@ -351,25 +358,6 @@ describe("verifyOnchainState", () => { }, }; - const mockPaymentRequirements: PaymentRequirements = { - scheme: DEFERRRED_SCHEME, - network: "base-sepolia", - maxAmountRequired: "1000000", - resource: "https://example.com/resource", - description: "Test resource", - mimeType: "application/json", - payTo: sellerAddress, - maxTimeoutSeconds: 300, - asset: assetAddress, - extra: { - type: "new", - voucher: { - id: voucherId, - escrow: escrowAddress, - }, - }, - }; - let mockClient: ConnectedClient; beforeEach(() => { @@ -388,39 +376,33 @@ describe("verifyOnchainState", () => { it("should return undefined for valid onchain state", async () => { vi.mocked(mockClient.readContract) .mockResolvedValueOnce([BigInt(1_000_000)]) - .mockResolvedValueOnce({ balance: BigInt(10_000_000) }); - - const result = await verifyOnchainState( - mockClient, - mockPaymentPayload, - mockPaymentRequirements, - ); - expect(result).toBeUndefined(); + .mockResolvedValueOnce({ + balance: BigInt(10_000_000), + thawingAmount: BigInt(0), + thawEndTime: BigInt(0), + }); + + const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); + // verifyOnchainState returns { isValid: true } for valid state + expect(result).toEqual({ isValid: true }); }); it("should return error if network is not supported", async () => { - vi.mocked(getNetworkId).mockImplementation(() => { - throw new Error("Unsupported network"); - }); - const result = await verifyOnchainState( - mockClient, - mockPaymentPayload, - mockPaymentRequirements, - ); + // This test doesn't make sense for verifyOnchainState which doesn't call getNetworkId + // The network check is done in verifyPaymentRequirements + // Updating to test actual behavior + vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); + const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); expect(result).toEqual({ isValid: false, - invalidReason: "invalid_network_unsupported", + invalidReason: "invalid_deferred_evm_contract_call_failed_outstanding_amount", payer: buyerAddress, }); }); it("should return error if client network mismatch", async () => { mockClient.chain.id = 1; - const result = await verifyOnchainState( - mockClient, - mockPaymentPayload, - mockPaymentRequirements, - ); + const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); expect(result).toEqual({ isValid: false, invalidReason: "invalid_client_network", @@ -430,11 +412,7 @@ describe("verifyOnchainState", () => { it("should return error if outstanding amount check fails", async () => { vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); - const result = await verifyOnchainState( - mockClient, - mockPaymentPayload, - mockPaymentRequirements, - ); + const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_contract_call_failed_outstanding_amount", @@ -446,11 +424,7 @@ describe("verifyOnchainState", () => { vi.mocked(mockClient.readContract) .mockResolvedValueOnce([BigInt(1_000_000)]) .mockRejectedValueOnce(new Error("Contract call failed")); - const result = await verifyOnchainState( - mockClient, - mockPaymentPayload, - mockPaymentRequirements, - ); + const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_contract_call_failed_account", @@ -461,13 +435,13 @@ describe("verifyOnchainState", () => { it("should return error if insufficient balance", async () => { vi.mocked(mockClient.readContract) .mockResolvedValueOnce([BigInt(1_000_000)]) - .mockResolvedValueOnce({ balance: BigInt(100_000) }); + .mockResolvedValueOnce({ + balance: BigInt(100_000), + thawingAmount: BigInt(0), + thawEndTime: BigInt(0), + }); - const result = await verifyOnchainState( - mockClient, - mockPaymentPayload, - mockPaymentRequirements, - ); + const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); expect(result).toEqual({ isValid: false, invalidReason: "insufficient_funds", diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 0a5e3bbdc0..2177ecc6bd 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -152,7 +152,7 @@ export type DeferredVoucherResponse = z.infer Date: Tue, 26 Aug 2025 12:20:58 -0300 Subject: [PATCH 049/116] chore: lint code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/types/verify/x402Specs.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index ecd3f4b4c4..82a5050172 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -65,6 +65,7 @@ export const UnsignedPaymentPayloadSchema = z.discriminatedUnion("scheme", [ ]); export type UnsignedPaymentPayload = z.infer; +<<<<<<< HEAD // x402 Resource Server Response export const x402ResponseSchema = z.object({ x402Version: z.number().refine(val => x402Versions.includes(val as 1)), @@ -137,6 +138,14 @@ export const VerifyRequestSchema = z.object({ paymentRequirements: PaymentRequirementsSchema, }); export type VerifyRequest = z.infer; +======= +// x402Request +export const X402RequestSchema = z.object({ + paymentRequirements: PaymentRequirementsSchema, + paymentPayload: PaymentPayloadSchema, +}); +export type X402Request = z.infer; +>>>>>>> d96a8bb (chore: lint code) // x402VerifyResponse export const VerifyResponseSchema = z.object({ From 4e55b668659b7e5e1bc66ced5a42e8e0e53103c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 26 Aug 2025 15:51:52 -0300 Subject: [PATCH 050/116] test: add tests to useDeferred facilitator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/verify/useDeferred.test.ts | 597 ++++++++++++++++++ .../packages/x402/src/verify/useDeferred.ts | 16 +- 2 files changed, 602 insertions(+), 11 deletions(-) create mode 100644 typescript/packages/x402/src/verify/useDeferred.test.ts diff --git a/typescript/packages/x402/src/verify/useDeferred.test.ts b/typescript/packages/x402/src/verify/useDeferred.test.ts new file mode 100644 index 0000000000..f7f5d7dbbc --- /dev/null +++ b/typescript/packages/x402/src/verify/useDeferred.test.ts @@ -0,0 +1,597 @@ +import { describe, expect, it, vi, beforeEach, afterEach } from "vitest"; +import { useDeferredFacilitator } from "./useDeferred"; +import { DEFAULT_FACILITATOR_URL } from "./useFacilitator"; +import { + DeferredEvmPayloadSignedVoucher, + DeferredErrorResponse, + DeferredVoucherResponse, + DeferredVouchersResponse, +} from "../types"; + +// Mock fetch globally +const mockFetch = vi.fn(); +global.fetch = mockFetch; + +describe("useDeferredFacilitator", () => { + const customFacilitatorUrl = "https://custom.facilitator.com/api"; + + const buyerAddress = "0xf33332f96E5EA32c90a5301b646Bf5e93EA1D892"; + const sellerAddress = "0x1234567890123456789012345678901234567890"; + const escrowAddress = "0xffffff12345678901234567890123456789fffff"; + const assetAddress = "0x1111111111111111111111111111111111111111"; + const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; + const voucherSignature = + "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c"; + + const mockSignedVoucher: DeferredEvmPayloadSignedVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: voucherSignature, + }; + + beforeEach(() => { + vi.clearAllMocks(); + mockFetch.mockReset(); + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + describe("useDeferredFacilitator initialization and configuration", () => { + it("should instantiate a valid facilitator", () => { + const facilitator = useDeferredFacilitator(); + expect(facilitator).toHaveProperty("getVoucher"); + expect(facilitator).toHaveProperty("getVoucherSeries"); + expect(facilitator).toHaveProperty("getVouchers"); + expect(facilitator).toHaveProperty("getAvailableVoucher"); + expect(facilitator).toHaveProperty("storeVoucher"); + expect(facilitator).toHaveProperty("verifyVoucher"); + expect(facilitator).toHaveProperty("settleVoucher"); + }); + + it("should use default facilitator URL when no config provided", async () => { + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockSignedVoucher), + }); + + const facilitator = useDeferredFacilitator(); + await facilitator.getVoucher(voucherId, 0); + + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/${voucherId}/0`, + ); + }); + + it("should use custom facilitator URL when config provided", async () => { + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockSignedVoucher), + }); + + const facilitator = useDeferredFacilitator({ url: customFacilitatorUrl }); + await facilitator.getVoucher(voucherId, 0); + + expect(mockFetch).toHaveBeenCalledWith( + `${customFacilitatorUrl}/deferred/vouchers/${voucherId}/0`, + ); + }); + }); + + describe("getVoucher", () => { + it("should fetch voucher successfully", async () => { + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockSignedVoucher), + }); + + const facilitator = useDeferredFacilitator(); + const result = await facilitator.getVoucher(voucherId, 0); + + expect(result).toEqual(mockSignedVoucher); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/${voucherId}/0`, + ); + }); + + it("should throw error for non-200 status", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Voucher not found", + }; + + mockFetch.mockResolvedValueOnce({ + status: 404, + statusText: "Not Found", + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.getVoucher(voucherId, 0)).rejects.toThrow("Voucher not found"); + }); + + it("should throw error when response contains error field", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Internal server error", + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.getVoucher(voucherId, 0)).rejects.toThrow("Internal server error"); + }); + + it("should use fallback error message when no error field", async () => { + mockFetch.mockResolvedValueOnce({ + status: 500, + statusText: "Internal Server Error", + json: () => Promise.resolve({}), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.getVoucher(voucherId, 0)).rejects.toThrow( + "Failed to fetch voucher history: Internal Server Error", + ); + }); + }); + + describe("getVoucherSeries", () => { + it("should fetch voucher series without pagination", async () => { + const mockResponse: DeferredVouchersResponse = { + data: [mockSignedVoucher], + count: 1, + pagination: { limit: 10, offset: 0 }, + }; + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator(); + const result = await facilitator.getVoucherSeries(voucherId, {}); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/${voucherId}`, + ); + }); + + it("should fetch voucher series with pagination", async () => { + const mockResponse: DeferredVouchersResponse = { + data: [mockSignedVoucher], + count: 1, + pagination: { limit: 10, offset: 5 }, + }; + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator(); + const result = await facilitator.getVoucherSeries(voucherId, { limit: 10, offset: 5 }); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/${voucherId}?limit=10&offset=5`, + ); + }); + + it("should throw error for non-200 status", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Series not found", + }; + + mockFetch.mockResolvedValueOnce({ + status: 404, + statusText: "Not Found", + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.getVoucherSeries(voucherId, {})).rejects.toThrow("Series not found"); + }); + + it("should throw error when response contains error field", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Internal server error", + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.getVoucherSeries(voucherId, {})).rejects.toThrow( + "Internal server error", + ); + }); + + it("should use fallback error message when no error field", async () => { + mockFetch.mockResolvedValueOnce({ + status: 500, + statusText: "Internal Server Error", + json: () => Promise.resolve({}), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.getVoucherSeries(voucherId, {})).rejects.toThrow( + "Failed to fetch voucher history: Internal Server Error", + ); + }); + }); + + describe("getVouchers", () => { + it("should fetch vouchers with basic query", async () => { + const mockResponse: DeferredVouchersResponse = { + data: [mockSignedVoucher], + count: 1, + pagination: { limit: 10, offset: 0 }, + }; + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator(); + const result = await facilitator.getVouchers( + { buyer: buyerAddress, seller: sellerAddress }, + {}, + ); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers?buyer=${buyerAddress}&seller=${sellerAddress}`, + ); + }); + + it("should fetch vouchers with pagination and filters", async () => { + const mockResponse: DeferredVouchersResponse = { + data: [mockSignedVoucher], + count: 1, + pagination: { limit: 50, offset: 10 }, + }; + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator(); + const result = await facilitator.getVouchers( + { buyer: buyerAddress, seller: sellerAddress, latest: true }, + { limit: 50, offset: 10 }, + ); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers?limit=50&offset=10&latest=true&buyer=${buyerAddress}&seller=${sellerAddress}`, + ); + }); + + it("should throw error for non-200 status", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Query failed", + }; + + mockFetch.mockResolvedValueOnce({ + status: 400, + statusText: "Bad Request", + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect( + facilitator.getVouchers({ buyer: buyerAddress, seller: sellerAddress }, {}), + ).rejects.toThrow("Query failed"); + }); + + it("should throw error when response contains error field", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Internal server error", + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect( + facilitator.getVouchers({ buyer: buyerAddress, seller: sellerAddress }, {}), + ).rejects.toThrow("Internal server error"); + }); + + it("should use fallback error message when no error field", async () => { + mockFetch.mockResolvedValueOnce({ + status: 500, + statusText: "Internal Server Error", + json: () => Promise.resolve({}), + }); + + const facilitator = useDeferredFacilitator(); + + await expect( + facilitator.getVouchers({ buyer: buyerAddress, seller: sellerAddress }, {}), + ).rejects.toThrow("Failed to fetch voucher history: Internal Server Error"); + }); + }); + + describe("getAvailableVoucher", () => { + it("should fetch available voucher successfully", async () => { + const mockResponse: DeferredVoucherResponse = mockSignedVoucher; + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator(); + const result = await facilitator.getAvailableVoucher(buyerAddress, sellerAddress); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/available/${buyerAddress}/${sellerAddress}`, + ); + }); + + it("should handle 404 status gracefully", async () => { + mockFetch.mockResolvedValueOnce({ + status: 404, + json: () => Promise.resolve({ error: "voucher_not_found" }), + }); + + const facilitator = useDeferredFacilitator(); + const result = await facilitator.getAvailableVoucher(buyerAddress, sellerAddress); + + expect(result).toEqual({ error: "voucher_not_found" }); + }); + + it("should throw error for other non-200 status codes", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Server error", + }; + + mockFetch.mockResolvedValueOnce({ + status: 500, + statusText: "Internal Server Error", + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.getAvailableVoucher(buyerAddress, sellerAddress)).rejects.toThrow( + "Server error", + ); + }); + + it("should throw error when response contains error field", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Voucher validation failed", + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.getAvailableVoucher(buyerAddress, sellerAddress)).rejects.toThrow( + "Voucher validation failed", + ); + }); + + it("should use fallback error message for non-200 status", async () => { + mockFetch.mockResolvedValueOnce({ + status: 403, + statusText: "Forbidden", + json: () => Promise.resolve({}), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.getAvailableVoucher(buyerAddress, sellerAddress)).rejects.toThrow( + "Failed to fetch available voucher: Forbidden", + ); + }); + }); + + describe("storeVoucher", () => { + it("should store voucher successfully", async () => { + const mockResponse: DeferredVoucherResponse = mockSignedVoucher; + mockFetch.mockResolvedValueOnce({ + status: 201, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator(); + const result = await facilitator.storeVoucher(mockSignedVoucher); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith(`${DEFAULT_FACILITATOR_URL}/deferred/vouchers`, { + method: "POST", + body: JSON.stringify(mockResponse), + headers: { + "Content-Type": "application/json", + }, + }); + }); + + it("should throw error for non-201 status", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Voucher invalid", + }; + + mockFetch.mockResolvedValueOnce({ + status: 400, + statusText: "Bad Request", + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.storeVoucher(mockSignedVoucher)).rejects.toThrow("Voucher invalid"); + }); + + it("should throw error when response contains error field", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Internal server error", + }; + + mockFetch.mockResolvedValueOnce({ + status: 201, + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.storeVoucher(mockSignedVoucher)).rejects.toThrow( + "Internal server error", + ); + }); + + it("should use fallback error message", async () => { + mockFetch.mockResolvedValueOnce({ + status: 500, + statusText: "Internal Server Error", + json: () => Promise.resolve({}), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.storeVoucher(mockSignedVoucher)).rejects.toThrow( + "Failed to store voucher: Internal Server Error", + ); + }); + }); + + describe("verifyVoucher", () => { + it("should verify voucher successfully", async () => { + const mockResponse = { isValid: true, payer: buyerAddress }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator(); + const result = await facilitator.verifyVoucher(voucherId, 0); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/${voucherId}/0/verify`, + { + method: "POST", + }, + ); + }); + + it("should throw error for non-200 status", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Verification failed", + }; + + mockFetch.mockResolvedValueOnce({ + status: 400, + statusText: "Bad Request", + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.verifyVoucher(voucherId, 0)).rejects.toThrow( + "Failed to verify voucher: Bad Request", + ); + }); + + it("should use fallback error message", async () => { + mockFetch.mockResolvedValueOnce({ + status: 404, + statusText: "Not Found", + json: () => Promise.resolve({}), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.verifyVoucher(voucherId, 0)).rejects.toThrow( + "Failed to verify voucher: Not Found", + ); + }); + }); + + describe("settleVoucher", () => { + it("should settle voucher successfully", async () => { + const mockResponse = { + success: true, + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator(); + const result = await facilitator.settleVoucher(voucherId, 0); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/${voucherId}/0/settle`, + { + method: "POST", + }, + ); + }); + + it("should throw error for non-200 status", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Settlement failed", + }; + + mockFetch.mockResolvedValueOnce({ + status: 500, + statusText: "Internal Server Error", + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.settleVoucher(voucherId, 0)).rejects.toThrow( + "Failed to settle voucher: Internal Server Error", + ); + }); + + it("should use fallback error message", async () => { + mockFetch.mockResolvedValueOnce({ + status: 503, + statusText: "Service Unavailable", + json: () => Promise.resolve({}), + }); + + const facilitator = useDeferredFacilitator(); + + await expect(facilitator.settleVoucher(voucherId, 0)).rejects.toThrow( + "Failed to settle voucher: Service Unavailable", + ); + }); + }); +}); diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index f3e30ec52f..ad71875e2a 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -111,9 +111,7 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { if (seller !== undefined) params.append("seller", seller); const queryString = params.toString(); - const response = await fetch( - `${url}/deferred/vouchers?${queryString ? `?${queryString}` : ""}`, - ); + const response = await fetch(`${url}/deferred/vouchers${queryString ? `?${queryString}` : ""}`); const responseJson = (await response.json()) as DeferredVouchersResponse; if (response.status !== 200 || "error" in responseJson) { @@ -176,9 +174,9 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { "Content-Type": "application/json", }, }); - const responseJson = await response.json(); + const responseJson = (await response.json()) as DeferredVoucherResponse; - if (response.status !== 201) { + if (response.status !== 201 || "error" in responseJson) { const errorMessage = (responseJson as DeferredErrorResponse).error || `Failed to store voucher: ${response.statusText}`; @@ -204,9 +202,7 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { const responseJson = await response.json(); if (response.status !== 200) { - const errorMessage = - (responseJson as DeferredErrorResponse).error || - `Failed to verify voucher: ${response.statusText}`; + const errorMessage = `Failed to verify voucher: ${response.statusText}`; throw new Error(errorMessage); } @@ -229,9 +225,7 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { const responseJson = await response.json(); if (response.status !== 200) { - const errorMessage = - (responseJson as DeferredErrorResponse).error || - `Failed to settle voucher: ${response.statusText}`; + const errorMessage = `Failed to settle voucher: ${response.statusText}`; throw new Error(errorMessage); } From 654936e57f3a2f492cb994375e1d4e2d7e095c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 26 Aug 2025 16:11:13 -0300 Subject: [PATCH 051/116] test: add id generation tests for deferred MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/schemes/deferred/evm/id.test.ts | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/id.test.ts diff --git a/typescript/packages/x402/src/schemes/deferred/evm/id.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/id.test.ts new file mode 100644 index 0000000000..8500e71182 --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/id.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "vitest"; +import { generateVoucherId } from "./id"; + +describe("generateVoucherId", () => { + it("should generate a valid voucher ID with 0x prefix", () => { + const voucherId = generateVoucherId(); + + expect(voucherId).toMatch(/^0x[a-f0-9]{64}$/i); + expect(voucherId).toHaveLength(66); // 0x + 64 hex characters + }); + + it("should generate unique IDs on multiple calls", () => { + const ids = new Set(); + const count = 1000; + + for (let i = 0; i < count; i++) { + ids.add(generateVoucherId()); + } + + expect(ids.size).toBe(count); + }); + + it("should generate IDs with proper hex format", () => { + const voucherId = generateVoucherId(); + + // Should start with 0x + expect(voucherId.startsWith("0x")).toBe(true); + + // Should contain only valid hex characters after 0x + const hexPart = voucherId.slice(2); + expect(hexPart).toMatch(/^[a-f0-9]+$/i); + expect(hexPart).toHaveLength(64); + }); +}); From e702923a8e08517952497fc4a94b049dbaaae6cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 26 Aug 2025 16:14:30 -0300 Subject: [PATCH 052/116] test: add deferred tests to useFacilitator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/verify/useFacilitator.test.ts | 413 +++++++++++++----- 1 file changed, 311 insertions(+), 102 deletions(-) diff --git a/typescript/packages/x402/src/verify/useFacilitator.test.ts b/typescript/packages/x402/src/verify/useFacilitator.test.ts index d81e5dc526..5cb527da2e 100644 --- a/typescript/packages/x402/src/verify/useFacilitator.test.ts +++ b/typescript/packages/x402/src/verify/useFacilitator.test.ts @@ -32,6 +32,98 @@ describe("useFacilitator", () => { asset: "0x1234567890123456789012345678901234567890", }; + const mockDeferredPaymentRequirements: PaymentRequirements = { + scheme: "deferred", + network: "base-sepolia", + maxAmountRequired: "20", + resource: "http://localhost:3002/subgraph/1234", + description: "", + mimeType: "", + payTo: "0xC93d37AD45c907eE1b27a02b2E1bd823BA9D379C", + maxTimeoutSeconds: 60, + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + extra: { + type: "new", + voucher: { + id: "0x198e73e1cecf59db4fbf8ca10000000000000000000000000000000000000000", + escrow: "0x1a9ea876cfe472514967d2e5cf326fb49dc68559", + }, + }, + }; + + const mockDeferredPaymentPayload: PaymentPayload = { + x402Version: 1, + scheme: "deferred", + network: "base-sepolia", + payload: { + signature: + "0xa80421aca752ab2e10b7e073f636bb50ccaec54f2813f8c194b45256460b5603340ce9ce75c12d0dabbe64e2011907f4c887064a39c36f633cb232b45dbec4611c", + voucher: { + nonce: 0, + id: "0x198e73e1cecf59db4fbf8ca10000000000000000000000000000000000000000", + escrow: "0x1a9ea876cfe472514967d2e5cf326fb49dc68559", + buyer: "0x80cdF1957EBb7a2DF22dd8913753A4423FF4272E", + seller: "0xC93d37AD45c907eE1b27a02b2E1bd823BA9D379C", + valueAggregate: "20", + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + timestamp: 1756226264, + chainId: 84532, + expiry: 1758818264, + }, + }, + }; + + const mockDeferredAggregatedPaymentRequirements: PaymentRequirements = { + scheme: "deferred", + network: "base-sepolia", + maxAmountRequired: "20", + resource: "http://localhost:3002/subgraph/1234", + description: "", + mimeType: "", + payTo: "0xC93d37AD45c907eE1b27a02b2E1bd823BA9D379C", + maxTimeoutSeconds: 60, + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + extra: { + type: "aggregation", + signature: + "0xa80421aca752ab2e10b7e073f636bb50ccaec54f2813f8c194b45256460b5603340ce9ce75c12d0dabbe64e2011907f4c887064a39c36f633cb232b45dbec4611c", + voucher: { + nonce: 0, + id: "0x198e73e1cecf59db4fbf8ca10000000000000000000000000000000000000000", + escrow: "0x1a9ea876cfe472514967d2e5cf326fb49dc68559", + buyer: "0x80cdF1957EBb7a2DF22dd8913753A4423FF4272E", + seller: "0xC93d37AD45c907eE1b27a02b2E1bd823BA9D379C", + valueAggregate: "20", + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + timestamp: 1756226264, + chainId: 84532, + expiry: 1758818264, + }, + }, + }; + + const mockDeferredAggregatedPaymentPayload: PaymentPayload = { + x402Version: 1, + scheme: "deferred", + network: "base-sepolia", + payload: { + signature: + "0xdf13d8f233a508ed40a85236df422d38edd0ad5ca3cb4e73d86cb712869919e82606bc2c29ace0d2a804b61808f099cf78d83b709ef1ea631b1496149cbfb1ea1c", + voucher: { + nonce: 1, + id: "0x198e73e1cecf59db4fbf8ca10000000000000000000000000000000000000000", + escrow: "0x1a9ea876cfe472514967d2e5cf326fb49dc68559", + buyer: "0x80cdF1957EBb7a2DF22dd8913753A4423FF4272E", + seller: "0xC93d37AD45c907eE1b27a02b2E1bd823BA9D379C", + valueAggregate: "40", + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + timestamp: 1756226267, + chainId: 84532, + expiry: 1758818267, + }, + }, + }; + beforeEach(() => { vi.clearAllMocks(); global.fetch = vi.fn().mockResolvedValue({ @@ -42,132 +134,249 @@ describe("useFacilitator", () => { }); describe("verify", () => { - it("should call fetch with the correct data and default URL", async () => { - const { verify } = useFacilitator(); - await verify(mockPaymentPayload, mockPaymentRequirements); - - expect(fetch).toHaveBeenCalledWith("https://x402.org/facilitator/verify", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - x402Version: mockPaymentPayload.x402Version, - paymentPayload: mockPaymentPayload, - paymentRequirements: mockPaymentRequirements, - }), + describe("exact scheme", () => { + it("should call fetch with the correct data and default URL", async () => { + const { verify } = useFacilitator(); + await verify(mockPaymentPayload, mockPaymentRequirements); + + expect(fetch).toHaveBeenCalledWith("https://x402.org/facilitator/verify", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + x402Version: mockPaymentPayload.x402Version, + paymentPayload: mockPaymentPayload, + paymentRequirements: mockPaymentRequirements, + }), + }); }); - }); - - it("should use custom URL when provided", async () => { - const customUrl = "https://custom-facilitator.org"; - const { verify } = useFacilitator({ url: customUrl }); - await verify(mockPaymentPayload, mockPaymentRequirements); - expect(fetch).toHaveBeenCalledWith(`${customUrl}/verify`, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - x402Version: mockPaymentPayload.x402Version, - paymentPayload: mockPaymentPayload, - paymentRequirements: mockPaymentRequirements, - }), + it("should use custom URL when provided", async () => { + const customUrl = "https://custom-facilitator.org"; + const { verify } = useFacilitator({ url: customUrl }); + await verify(mockPaymentPayload, mockPaymentRequirements); + + expect(fetch).toHaveBeenCalledWith(`${customUrl}/verify`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + x402Version: mockPaymentPayload.x402Version, + paymentPayload: mockPaymentPayload, + paymentRequirements: mockPaymentRequirements, + }), + }); }); - }); - it("should include auth headers when createAuthHeaders is provided", async () => { - const mockHeaders = { - verify: { Authorization: "Bearer test-token" }, - settle: { Authorization: "Bearer test-token" }, - }; - const { verify } = useFacilitator({ - url: "https://x402.org/facilitator", - createAuthHeaders: async () => mockHeaders, + it("should include auth headers when createAuthHeaders is provided", async () => { + const mockHeaders = { + verify: { Authorization: "Bearer test-token" }, + settle: { Authorization: "Bearer test-token" }, + }; + const { verify } = useFacilitator({ + url: "https://x402.org/facilitator", + createAuthHeaders: async () => mockHeaders, + }); + await verify(mockPaymentPayload, mockPaymentRequirements); + + expect(fetch).toHaveBeenCalledWith( + "https://x402.org/facilitator/verify", + expect.objectContaining({ + headers: { "Content-Type": "application/json", ...mockHeaders.verify }, + }), + ); }); - await verify(mockPaymentPayload, mockPaymentRequirements); - expect(fetch).toHaveBeenCalledWith( - "https://x402.org/facilitator/verify", - expect.objectContaining({ - headers: { "Content-Type": "application/json", ...mockHeaders.verify }, - }), - ); + it("should throw error on non-200 response", async () => { + global.fetch = vi.fn().mockResolvedValue({ + status: 400, + statusText: "Bad Request", + json: async () => ({}), + }); + const { verify } = useFacilitator(); + + await expect(verify(mockPaymentPayload, mockPaymentRequirements)).rejects.toThrow( + "Failed to verify payment: Bad Request", + ); + }); }); - it("should throw error on non-200 response", async () => { - global.fetch = vi.fn().mockResolvedValue({ - status: 400, - statusText: "Bad Request", - json: async () => ({}), + describe("deferred scheme", () => { + it("should call fetch with the correct data and default URL", async () => { + global.fetch = vi.fn().mockResolvedValue({ + status: 200, + json: async () => ({ + isValid: true, + payer: mockDeferredPaymentPayload.payload.voucher.buyer, + }), + }); + + const { verify } = useFacilitator(); + await verify(mockDeferredPaymentPayload, mockDeferredPaymentRequirements); + + expect(fetch).toHaveBeenCalledWith("https://x402.org/facilitator/verify", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + x402Version: mockDeferredPaymentPayload.x402Version, + paymentPayload: mockDeferredPaymentPayload, + paymentRequirements: mockDeferredPaymentRequirements, + }), + }); }); - const { verify } = useFacilitator(); - await expect(verify(mockPaymentPayload, mockPaymentRequirements)).rejects.toThrow( - "Failed to verify payment: Bad Request", - ); + it("should call fetch with the correct data and default URL for aggregated payment", async () => { + global.fetch = vi.fn().mockResolvedValue({ + status: 200, + json: async () => ({ + isValid: true, + payer: mockDeferredAggregatedPaymentPayload.payload.voucher.buyer, + }), + }); + + const { verify } = useFacilitator(); + const result = await verify( + mockDeferredAggregatedPaymentPayload, + mockDeferredAggregatedPaymentRequirements, + ); + + expect(result).toEqual({ + isValid: true, + payer: mockDeferredAggregatedPaymentPayload.payload.voucher.buyer, + }); + expect(fetch).toHaveBeenCalledWith("https://x402.org/facilitator/verify", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + x402Version: mockDeferredAggregatedPaymentPayload.x402Version, + paymentPayload: mockDeferredAggregatedPaymentPayload, + paymentRequirements: mockDeferredAggregatedPaymentRequirements, + }), + }); + }); }); }); describe("settle", () => { - it("should call fetch with the correct data and default URL", async () => { - const { settle } = useFacilitator(); - await settle(mockPaymentPayload, mockPaymentRequirements); - - expect(fetch).toHaveBeenCalledWith("https://x402.org/facilitator/settle", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - x402Version: mockPaymentPayload.x402Version, - paymentPayload: mockPaymentPayload, - paymentRequirements: mockPaymentRequirements, - }), + describe("exact scheme", () => { + it("should call fetch with the correct data and default URL", async () => { + const { settle } = useFacilitator(); + await settle(mockPaymentPayload, mockPaymentRequirements); + + expect(fetch).toHaveBeenCalledWith("https://x402.org/facilitator/settle", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + x402Version: mockPaymentPayload.x402Version, + paymentPayload: mockPaymentPayload, + paymentRequirements: mockPaymentRequirements, + }), + }); }); - }); - it("should use custom URL when provided", async () => { - const customUrl = "https://custom-facilitator.org"; - const { settle } = useFacilitator({ url: customUrl }); - await settle(mockPaymentPayload, mockPaymentRequirements); - - expect(fetch).toHaveBeenCalledWith(`${customUrl}/settle`, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - x402Version: mockPaymentPayload.x402Version, - paymentPayload: mockPaymentPayload, - paymentRequirements: mockPaymentRequirements, - }), + it("should use custom URL when provided", async () => { + const customUrl = "https://custom-facilitator.org"; + const { settle } = useFacilitator({ url: customUrl }); + await settle(mockPaymentPayload, mockPaymentRequirements); + + expect(fetch).toHaveBeenCalledWith(`${customUrl}/settle`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + x402Version: mockPaymentPayload.x402Version, + paymentPayload: mockPaymentPayload, + paymentRequirements: mockPaymentRequirements, + }), + }); }); - }); - it("should include auth headers when createAuthHeaders is provided", async () => { - const mockHeaders = { - verify: { Authorization: "Bearer test-token" }, - settle: { Authorization: "Bearer test-token" }, - }; - const { settle } = useFacilitator({ - url: "https://x402.org/facilitator", - createAuthHeaders: async () => mockHeaders, + it("should include auth headers when createAuthHeaders is provided", async () => { + const mockHeaders = { + verify: { Authorization: "Bearer test-token" }, + settle: { Authorization: "Bearer test-token" }, + }; + const { settle } = useFacilitator({ + url: "https://x402.org/facilitator", + createAuthHeaders: async () => mockHeaders, + }); + await settle(mockPaymentPayload, mockPaymentRequirements); + + expect(fetch).toHaveBeenCalledWith( + "https://x402.org/facilitator/settle", + expect.objectContaining({ + headers: { "Content-Type": "application/json", ...mockHeaders.settle }, + }), + ); }); - await settle(mockPaymentPayload, mockPaymentRequirements); - expect(fetch).toHaveBeenCalledWith( - "https://x402.org/facilitator/settle", - expect.objectContaining({ - headers: { "Content-Type": "application/json", ...mockHeaders.settle }, - }), - ); + it("should throw error on non-200 response", async () => { + global.fetch = vi.fn().mockResolvedValue({ + status: 400, + statusText: "Bad Request", + json: async () => ({}), + }); + const { settle } = useFacilitator(); + + await expect(settle(mockPaymentPayload, mockPaymentRequirements)).rejects.toThrow( + "Failed to settle payment: 400 Bad Request", + ); + }); }); - it("should throw error on non-200 response", async () => { - global.fetch = vi.fn().mockResolvedValue({ - status: 400, - statusText: "Bad Request", - json: async () => ({}), + describe("deferred scheme", () => { + it("should call fetch with the correct data and default URL", async () => { + global.fetch = vi.fn().mockResolvedValue({ + status: 200, + json: async () => ({ + success: true, + transaction: "0x1234567890abcdef", + payer: mockDeferredPaymentPayload.payload.voucher.buyer, + }), + }); + + const { settle } = useFacilitator(); + await settle(mockDeferredPaymentPayload, mockDeferredPaymentRequirements); + + expect(fetch).toHaveBeenCalledWith("https://x402.org/facilitator/settle", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + x402Version: mockDeferredPaymentPayload.x402Version, + paymentPayload: mockDeferredPaymentPayload, + paymentRequirements: mockDeferredPaymentRequirements, + }), + }); }); - const { settle } = useFacilitator(); - await expect(settle(mockPaymentPayload, mockPaymentRequirements)).rejects.toThrow( - "Failed to settle payment: 400 Bad Request", - ); + it("should call fetch with the correct data and default URL for aggregated payment", async () => { + global.fetch = vi.fn().mockResolvedValue({ + status: 200, + json: async () => ({ + success: true, + transaction: "0xabcdef1234567890", + payer: mockDeferredAggregatedPaymentPayload.payload.voucher.buyer, + }), + }); + + const { settle } = useFacilitator(); + const result = await settle( + mockDeferredAggregatedPaymentPayload, + mockDeferredAggregatedPaymentRequirements, + ); + + expect(result).toEqual({ + success: true, + transaction: "0xabcdef1234567890", + payer: mockDeferredAggregatedPaymentPayload.payload.voucher.buyer, + }); + expect(fetch).toHaveBeenCalledWith("https://x402.org/facilitator/settle", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + x402Version: mockDeferredAggregatedPaymentPayload.x402Version, + paymentPayload: mockDeferredAggregatedPaymentPayload, + paymentRequirements: mockDeferredAggregatedPaymentRequirements, + }), + }); + }); }); }); From 466a7d648f3ae6ba092778fc59a3a32fe3a29a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 26 Aug 2025 17:38:35 -0300 Subject: [PATCH 053/116] test: add tests for verify deferred, fix some bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/verify.test.ts | 947 ++++++++++++++++-- .../x402/src/schemes/deferred/evm/verify.ts | 7 +- 2 files changed, 851 insertions(+), 103 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts index ad9773f755..a827c0a35a 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts @@ -3,25 +3,34 @@ import { PaymentRequirements } from "../../../types"; import { DeferredPaymentPayload, DeferredPaymentRequirements, + DeferredEvmPayloadSignedVoucher, DEFERRRED_SCHEME, } from "../../../types/verify/schemes/deferred"; -import { verifyPaymentRequirements, verifyVoucherSignature, verifyOnchainState } from "./verify"; -import { ConnectedClient } from "../../../types/shared/evm/wallet"; -import { verifyVoucher } from "./sign"; +import { + verifyPaymentRequirements, + verifyVoucherSignature, + verifyOnchainState, + verifyVoucherContinuity, + verifyPreviousVoucherAvailability, + verifyVoucherDuplicate, +} from "./verify"; +import { ConnectedClient, createSigner } from "../../../types/shared/evm/wallet"; import { getNetworkId } from "../../../shared"; -import { Account, Chain, Transport } from "viem"; - -vi.mock("./sign", () => ({ - verifyVoucher: vi.fn(), -})); +import { VoucherStore } from "./store"; +import { Account, Chain, getAddress, Transport } from "viem"; +import { signVoucher } from "./sign"; vi.mock("../../../shared", () => ({ getNetworkId: vi.fn(), })); -const buyerAddress = "0xf33332f96E5EA32c90a5301b646Bf5e93EA1D892"; +const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", +); +const buyerAddress = "0x05159b6100E8c7A3BbaE174A94c32E1E2e37059b"; const sellerAddress = "0x1234567890123456789012345678901234567890"; -const escrowAddress = "0xffffff12345678901234567890123456789fffff"; +const escrowAddress = "0xffFfFf12345678901234567890123456789fffFF"; const assetAddress = "0x1111111111111111111111111111111111111111"; const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; const voucherSignature = @@ -79,12 +88,12 @@ describe("verifyPaymentRequirements", () => { vi.resetAllMocks(); }); - it("should return undefined for valid payment requirements with new voucher", async () => { - const result = await verifyPaymentRequirements(mockPaymentPayload, mockPaymentRequirements); + it("should return isValid: true for valid payment requirements with new voucher", () => { + const result = verifyPaymentRequirements(mockPaymentPayload, mockPaymentRequirements); expect(result).toEqual({ isValid: true }); }); - it("should return undefined for valid payment requirements with aggregation voucher", async () => { + it("should return isValid: true for valid payment requirements with aggregation voucher", () => { const aggregationRequirements: PaymentRequirements = { ...mockPaymentRequirements, maxAmountRequired: "500000", @@ -97,23 +106,23 @@ describe("verifyPaymentRequirements", () => { }, }, }; - const result = await verifyPaymentRequirements(mockPaymentPayload, aggregationRequirements); + const result = verifyPaymentRequirements(mockPaymentPayload, aggregationRequirements); expect(result).toEqual({ isValid: true }); }); - it("should return error if payload scheme is not deferred", async () => { + it("should return error if payload scheme is not deferred", () => { const invalidPayload = { ...mockPaymentPayload, scheme: "immediate", } as unknown as DeferredPaymentPayload; - const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + const result = verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_payload_scheme", }); }); - it("should return error if requirements scheme is not deferred", async () => { + it("should return error if requirements scheme is not deferred", () => { const invalidRequirements = { ...mockPaymentRequirements, scheme: "immediate", @@ -128,12 +137,41 @@ describe("verifyPaymentRequirements", () => { }); }); - it("should return error if payment payload network does not match payment requirements network", async () => { + it("should return error if payment payload network does not match payment requirements network", () => { const invalidPayload = { ...mockPaymentPayload, network: "base", } as DeferredPaymentPayload; - const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + const result = verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_network_mismatch", + payer: buyerAddress, + }); + }); + + it("should return error if network is not supported", () => { + vi.mocked(getNetworkId).mockImplementation(() => { + throw new Error("Unsupported network"); + }); + const result = verifyPaymentRequirements(mockPaymentPayload, mockPaymentRequirements); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_network_unsupported", + payer: buyerAddress, + }); + vi.resetAllMocks(); + }); + + it("should return error if network is invalid", () => { + const invalidPayload = { + ...mockPaymentPayload, + network: "iotex", + payload: { + ...mockPaymentPayload.payload, + }, + } as DeferredPaymentPayload; + const result = verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_payload_network_mismatch", @@ -141,7 +179,7 @@ describe("verifyPaymentRequirements", () => { }); }); - it("should return error if voucher value is insufficient for new voucher", async () => { + it("should return error if voucher value is insufficient for new voucher", () => { const invalidPayload = { ...mockPaymentPayload, payload: { @@ -152,7 +190,7 @@ describe("verifyPaymentRequirements", () => { }, }, }; - const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + const result = verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_value", @@ -160,7 +198,7 @@ describe("verifyPaymentRequirements", () => { }); }); - it("should return error if voucher value is insufficient for aggregation voucher", async () => { + it("should return error if voucher value is insufficient for aggregation voucher", () => { const aggregationRequirements: PaymentRequirements = { ...mockPaymentRequirements, extra: { @@ -172,7 +210,7 @@ describe("verifyPaymentRequirements", () => { }, }, }; - const result = await verifyPaymentRequirements(mockPaymentPayload, aggregationRequirements); + const result = verifyPaymentRequirements(mockPaymentPayload, aggregationRequirements); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_value", @@ -180,12 +218,12 @@ describe("verifyPaymentRequirements", () => { }); }); - it("should return error if payTo does not match voucher seller", async () => { + it("should return error if payTo does not match voucher seller", () => { const invalidRequirements = { ...mockPaymentRequirements, payTo: "0x9999999999999999999999999999999999999999", }; - const result = await verifyPaymentRequirements(mockPaymentPayload, invalidRequirements); + const result = verifyPaymentRequirements(mockPaymentPayload, invalidRequirements); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_payload_recipient_mismatch", @@ -193,7 +231,7 @@ describe("verifyPaymentRequirements", () => { }); }); - it("should return error if asset mismatch", async () => { + it("should return error if asset mismatch", () => { const invalidPayload = { ...mockPaymentPayload, payload: { @@ -204,87 +242,480 @@ describe("verifyPaymentRequirements", () => { }, }, }; - const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + const result = verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_payload_asset_mismatch", payer: buyerAddress, }); }); +}); - it("should return error if network is not supported", async () => { - vi.mocked(getNetworkId).mockImplementation(() => { - throw new Error("Unsupported network"); +describe("verifyVoucherContinuity", () => { + const baseVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days + }; + + const basePaymentPayload: DeferredPaymentPayload = { + x402Version: 1, + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + payload: { + signature: voucherSignature, + voucher: baseVoucher, + }, + }; + + const aggregatedVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "12000000", + asset: assetAddress, + timestamp: 1715769600 + 100, + nonce: 1, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 60, // 60 days + }; + + const aggregatedPaymentPayload: DeferredPaymentPayload = { + x402Version: 1, + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + payload: { + signature: voucherSignature, // does not matter + voucher: aggregatedVoucher, + }, + }; + + const baseNewVoucherPaymentRequirements: PaymentRequirements = { + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test resource", + mimeType: "application/json", + payTo: sellerAddress, + maxTimeoutSeconds: 300, + asset: assetAddress, + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + }, + }; + + const baseAggregationVoucherPaymentRequirements: PaymentRequirements = { + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test resource", + mimeType: "application/json", + payTo: sellerAddress, + maxTimeoutSeconds: 300, + asset: assetAddress, + extra: { + type: "aggregation", + signature: voucherSignature, + voucher: baseVoucher, + }, + }; + + beforeEach(() => { + vi.clearAllMocks(); + // Mock current time to be within valid range + vi.useFakeTimers(); + vi.setSystemTime(new Date((baseVoucher.timestamp + 100) * 1000)); // 100 seconds after voucher timestamp + }); + + afterEach(() => { + vi.useRealTimers(); + vi.resetAllMocks(); + }); + + it("should return valid if new voucher is valid", () => { + const result = verifyVoucherContinuity(basePaymentPayload, baseNewVoucherPaymentRequirements); + expect(result).toEqual({ + isValid: true, }); - const result = await verifyPaymentRequirements(mockPaymentPayload, mockPaymentRequirements); + }); + + it("should return valid if aggregation voucher is valid", () => { + const result = verifyVoucherContinuity( + aggregatedPaymentPayload, + baseAggregationVoucherPaymentRequirements, + ); expect(result).toEqual({ - isValid: false, - invalidReason: "invalid_network_unsupported", - payer: buyerAddress, + isValid: true, }); }); - it("should return error if chainId mismatch", async () => { - const invalidPayload = { - ...mockPaymentPayload, + it("should return error if voucher is expired", () => { + const expiredPaymentPayload = { + ...basePaymentPayload, payload: { - ...mockPaymentPayload.payload, + ...basePaymentPayload.payload, voucher: { - ...mockVoucher, - chainId: 1, + ...baseVoucher, + expiry: baseVoucher.timestamp - 1000, }, }, }; - const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); + + const result = verifyVoucherContinuity( + expiredPaymentPayload, + baseNewVoucherPaymentRequirements, + ); + expect(result).toEqual({ isValid: false, - invalidReason: "invalid_deferred_evm_payload_chain_id", + invalidReason: "invalid_deferred_evm_payload_voucher_expired", payer: buyerAddress, }); }); - it("should return error if voucher is expired", async () => { - const now = Math.floor(Date.now() / 1000); - const invalidPayload = { - ...mockPaymentPayload, + it("should return error if voucher timestamp is in the future", () => { + const paymentPayload = { + ...basePaymentPayload, payload: { - ...mockPaymentPayload.payload, + ...basePaymentPayload.payload, voucher: { - ...mockVoucher, - expiry: now - 1, // 1 second in the past + ...baseVoucher, + timestamp: baseVoucher.timestamp + 3600, }, }, }; - const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); - // verifyPaymentRequirements doesn't check expiry, it returns isValid: true - expect(result).toEqual({ isValid: true }); + + const result = verifyVoucherContinuity(paymentPayload, baseNewVoucherPaymentRequirements); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_timestamp_too_early", + payer: buyerAddress, + }); }); - it("should return error if voucher timestamp is in the future", async () => { - const now = Math.floor(Date.now() / 1000); - const invalidPayload = { - ...mockPaymentPayload, - payload: { - ...mockPaymentPayload.payload, - voucher: { - ...mockVoucher, - timestamp: now + 3600, // 1 hour in the future + describe("new voucher validation", () => { + it("should return error if new voucher has non-zero nonce", () => { + const paymentPayload = { + ...basePaymentPayload, + payload: { + ...basePaymentPayload.payload, + voucher: { + ...baseVoucher, + nonce: 1, + }, }, - }, - }; - const result = await verifyPaymentRequirements(invalidPayload, mockPaymentRequirements); - // verifyPaymentRequirements doesn't check timestamp, it returns isValid: true - expect(result).toEqual({ isValid: true }); + }; + const result = verifyVoucherContinuity(paymentPayload, baseNewVoucherPaymentRequirements); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_non_zero_nonce", + payer: buyerAddress, + }); + }); + + it("should return error if new voucher has zero value aggregate", () => { + const paymentPayload = { + ...basePaymentPayload, + payload: { + ...basePaymentPayload.payload, + voucher: { ...baseVoucher, valueAggregate: "0" }, + }, + }; + const result = verifyVoucherContinuity(paymentPayload, baseNewVoucherPaymentRequirements); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_zero_value_aggregate", + payer: buyerAddress, + }); + }); + }); + + describe("aggregation voucher validation", () => { + it("should return error if voucher id doesn't match", () => { + const mismatchedIdVoucher = { + ...aggregatedVoucher, + id: "0x1111111111111111111111111111111111111111111111111111111111111111", + }; + + const paymentPayload = { + ...aggregatedPaymentPayload, + payload: { + ...aggregatedPaymentPayload.payload, + voucher: mismatchedIdVoucher, + }, + }; + + const result = verifyVoucherContinuity( + paymentPayload, + baseAggregationVoucherPaymentRequirements, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_id_mismatch", + payer: buyerAddress, + }); + }); + + it("should return error if buyer doesn't match", () => { + const mismatchedBuyerVoucher = { + ...aggregatedVoucher, + buyer: "0x9999999999999999999999999999999999999999", + }; + + const paymentPayload = { + ...aggregatedPaymentPayload, + payload: { + ...aggregatedPaymentPayload.payload, + voucher: mismatchedBuyerVoucher, + }, + }; + + const result = verifyVoucherContinuity( + paymentPayload, + baseAggregationVoucherPaymentRequirements, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_buyer_mismatch", + payer: "0x9999999999999999999999999999999999999999", + }); + }); + + it("should return error if seller doesn't match", () => { + const mismatchedSellerVoucher = { + ...aggregatedVoucher, + seller: "0x9999999999999999999999999999999999999999", + }; + + const paymentPayload = { + ...aggregatedPaymentPayload, + payload: { + ...aggregatedPaymentPayload.payload, + voucher: mismatchedSellerVoucher, + }, + }; + + const result = verifyVoucherContinuity( + paymentPayload, + baseAggregationVoucherPaymentRequirements, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_seller_mismatch", + payer: buyerAddress, + }); + }); + + it("should return error if value aggregate decreases", () => { + const decreasingValueVoucher = { + ...aggregatedVoucher, + valueAggregate: (BigInt(baseVoucher.valueAggregate) - BigInt(1)).toString(), + }; + + const paymentPayload = { + ...aggregatedPaymentPayload, + payload: { + ...aggregatedPaymentPayload.payload, + voucher: decreasingValueVoucher, + }, + }; + + const result = verifyVoucherContinuity( + paymentPayload, + baseAggregationVoucherPaymentRequirements, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_value_aggregate_decreasing", + payer: buyerAddress, + }); + }); + + it("should return error if asset doesn't match", () => { + const mismatchedAssetVoucher = { + ...aggregatedVoucher, + asset: "0x9999999999999999999999999999999999999999", + }; + + const paymentPayload = { + ...aggregatedPaymentPayload, + payload: { + ...aggregatedPaymentPayload.payload, + voucher: mismatchedAssetVoucher, + }, + }; + + const result = verifyVoucherContinuity( + paymentPayload, + baseAggregationVoucherPaymentRequirements, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_asset_mismatch", + payer: buyerAddress, + }); + }); + + it("should return error if timestamp decreases", () => { + const decreasingTimestampVoucher = { + ...aggregatedVoucher, + timestamp: baseVoucher.timestamp - 100, // Earlier than previous + }; + + const paymentPayload = { + ...aggregatedPaymentPayload, + payload: { + ...aggregatedPaymentPayload.payload, + voucher: decreasingTimestampVoucher, + }, + }; + + const result = verifyVoucherContinuity( + paymentPayload, + baseAggregationVoucherPaymentRequirements, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_timestamp_decreasing", + payer: buyerAddress, + }); + }); + + it("should return error if nonce is not incremented by 1", () => { + const wrongNonceVoucher = { + ...aggregatedVoucher, + nonce: 2, // Should be 1 + }; + + const paymentPayload = { + ...aggregatedPaymentPayload, + payload: { + ...aggregatedPaymentPayload.payload, + voucher: wrongNonceVoucher, + }, + }; + + const result = verifyVoucherContinuity( + paymentPayload, + baseAggregationVoucherPaymentRequirements, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_nonce_mismatch", + payer: buyerAddress, + }); + }); + + it("should return error if escrow doesn't match", () => { + const mismatchedEscrowVoucher = { + ...aggregatedVoucher, + escrow: "0x9999999999999999999999999999999999999999", + }; + + const paymentPayload = { + ...aggregatedPaymentPayload, + payload: { + ...aggregatedPaymentPayload.payload, + voucher: mismatchedEscrowVoucher, + }, + }; + + const result = verifyVoucherContinuity( + paymentPayload, + baseAggregationVoucherPaymentRequirements, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_escrow_mismatch", + payer: buyerAddress, + }); + }); + + it("should return error if chainId doesn't match", () => { + const mismatchedChainIdVoucher = { + ...aggregatedVoucher, + chainId: 1, // Different chain + }; + + const paymentPayload = { + ...aggregatedPaymentPayload, + payload: { + ...aggregatedPaymentPayload.payload, + voucher: mismatchedChainIdVoucher, + }, + }; + + const result = verifyVoucherContinuity( + paymentPayload, + baseAggregationVoucherPaymentRequirements, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_chain_id_mismatch", + payer: buyerAddress, + }); + }); + + it("should return error if expiry decreases", () => { + const decreasingExpiryVoucher = { + ...aggregatedVoucher, + expiry: baseVoucher.expiry - 1, // Earlier expiry + }; + + const paymentPayload = { + ...aggregatedPaymentPayload, + payload: { + ...aggregatedPaymentPayload.payload, + voucher: decreasingExpiryVoucher, + }, + }; + + const result = verifyVoucherContinuity( + paymentPayload, + baseAggregationVoucherPaymentRequirements, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_expiry_decreasing", + payer: buyerAddress, + }); + }); }); }); -describe("verifyVoucherSignature", () => { - const mockPaymentPayload: DeferredPaymentPayload = { +describe("verifyVoucherSignature", async () => { + const mockPaymentPayload = { x402Version: 1, scheme: DEFERRRED_SCHEME, network: "base-sepolia", payload: { - signature: voucherSignature, voucher: { id: voucherId, buyer: buyerAddress, @@ -299,41 +730,368 @@ describe("verifyVoucherSignature", () => { }, }, }; + const { signature } = await signVoucher(buyer, mockPaymentPayload.payload.voucher); + + it("should return isValid: true for valid voucher signature", async () => { + const result = await verifyVoucherSignature(mockPaymentPayload.payload.voucher, signature); + expect(result).toEqual({ isValid: true }); + }); + + it("should return isValid: false for invalid voucher signature", async () => { + const result = await verifyVoucherSignature( + mockPaymentPayload.payload.voucher, + "0x999b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c", + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_signature", + payer: buyerAddress, + }); + }); +}); + +describe("verifyPreviousVoucherAvailability", () => { + const mockVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + }; + + const mockSignedVoucher: DeferredEvmPayloadSignedVoucher = { + ...mockVoucher, + signature: voucherSignature, + }; + + let mockVoucherStore: VoucherStore; beforeEach(() => { vi.clearAllMocks(); + mockVoucherStore = { + getVoucher: vi.fn(), + } as unknown as VoucherStore; }); afterEach(() => { vi.resetAllMocks(); }); - it("should return undefined for valid voucher signature", async () => { - vi.mocked(verifyVoucher).mockResolvedValue(true); - const result = await verifyVoucherSignature( - mockPaymentPayload.payload.voucher, - mockPaymentPayload.payload.signature, + it("should return valid response when previous voucher is found and matches", async () => { + vi.mocked(mockVoucherStore.getVoucher).mockResolvedValue(mockSignedVoucher); + + const result = await verifyPreviousVoucherAvailability( + mockVoucher, + voucherSignature, + mockVoucherStore, ); - expect(result).toEqual({ isValid: true }); - expect(vi.mocked(verifyVoucher)).toHaveBeenCalledWith( - mockPaymentPayload.payload.voucher, + + expect(result).toEqual({ + isValid: true, + }); + + expect(mockVoucherStore.getVoucher).toHaveBeenCalledWith(voucherId, 0); + }); + + it("should return error when previous voucher is not found in store", async () => { + vi.mocked(mockVoucherStore.getVoucher).mockResolvedValue(null); + + const result = await verifyPreviousVoucherAvailability( + mockVoucher, voucherSignature, - buyerAddress, + mockVoucherStore, ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_previous_voucher_not_found", + payer: buyerAddress, + }); }); - it("should return error for invalid voucher signature", async () => { - vi.mocked(verifyVoucher).mockResolvedValue(false); - const result = await verifyVoucherSignature( - mockPaymentPayload.payload.voucher, - mockPaymentPayload.payload.signature, + it("should return error when previous voucher is found but doesn't match", async () => { + const mismatchedVoucher: DeferredEvmPayloadSignedVoucher = { + ...mockSignedVoucher, + valueAggregate: "500000", // Different value + }; + + vi.mocked(mockVoucherStore.getVoucher).mockResolvedValue(mismatchedVoucher); + + const result = await verifyPreviousVoucherAvailability( + mockVoucher, + voucherSignature, + mockVoucherStore, ); + expect(result).toEqual({ isValid: false, - invalidReason: "invalid_deferred_evm_payload_signature", + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", payer: buyerAddress, }); }); + + it("should handle voucher store errors", async () => { + vi.mocked(mockVoucherStore.getVoucher).mockRejectedValue(new Error("Store error")); + + await expect( + verifyPreviousVoucherAvailability(mockVoucher, voucherSignature, mockVoucherStore), + ).rejects.toThrow("Store error"); + }); +}); + +describe("verifyVoucherDuplicate", () => { + const baseVoucher: DeferredEvmPayloadSignedVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: voucherSignature, + }; + + it("should return valid response for identical vouchers", () => { + const identicalVoucher = { ...baseVoucher }; + + const result = verifyVoucherDuplicate(baseVoucher, identicalVoucher); + + expect(result).toEqual({ + isValid: true, + }); + }); + + it("should return error if voucher IDs don't match", () => { + const differentIdVoucher = { + ...baseVoucher, + id: "0x1111111111111111111111111111111111111111111111111111111111111111", + }; + + const result = verifyVoucherDuplicate(baseVoucher, differentIdVoucher); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: buyerAddress, + }); + }); + + it("should return error if buyer addresses don't match", () => { + const differentBuyerVoucher = { + ...baseVoucher, + buyer: "0x9999999999999999999999999999999999999999", + }; + + const result = verifyVoucherDuplicate(baseVoucher, differentBuyerVoucher); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: buyerAddress, + }); + }); + + it("should return error if seller addresses don't match", () => { + const differentSellerVoucher = { + ...baseVoucher, + seller: "0x9999999999999999999999999999999999999999", + }; + + const result = verifyVoucherDuplicate(baseVoucher, differentSellerVoucher); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: buyerAddress, + }); + }); + + it("should return error if value aggregates don't match", () => { + const differentValueVoucher = { + ...baseVoucher, + valueAggregate: "2000000", + }; + + const result = verifyVoucherDuplicate(baseVoucher, differentValueVoucher); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: buyerAddress, + }); + }); + + it("should return error if assets don't match", () => { + const differentAssetVoucher = { + ...baseVoucher, + asset: "0x2222222222222222222222222222222222222222", + }; + + const result = verifyVoucherDuplicate(baseVoucher, differentAssetVoucher); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: buyerAddress, + }); + }); + + it("should return error if timestamps don't match", () => { + const differentTimestampVoucher = { + ...baseVoucher, + timestamp: 1715769700, + }; + + const result = verifyVoucherDuplicate(baseVoucher, differentTimestampVoucher); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: buyerAddress, + }); + }); + + it("should return error if nonces don't match", () => { + const differentNonceVoucher = { + ...baseVoucher, + nonce: 1, + }; + + const result = verifyVoucherDuplicate(baseVoucher, differentNonceVoucher); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: buyerAddress, + }); + }); + + it("should return error if escrow addresses don't match", () => { + const differentEscrowVoucher = { + ...baseVoucher, + escrow: "0x9999999999999999999999999999999999999999", + }; + + const result = verifyVoucherDuplicate(baseVoucher, differentEscrowVoucher); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: buyerAddress, + }); + }); + + it("should return error if chain IDs don't match", () => { + const differentChainIdVoucher = { + ...baseVoucher, + chainId: 1, + }; + + const result = verifyVoucherDuplicate(baseVoucher, differentChainIdVoucher); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: buyerAddress, + }); + }); + + it("should return error if expiry times don't match", () => { + const differentExpiryVoucher = { + ...baseVoucher, + expiry: baseVoucher.expiry + 3600, + }; + + const result = verifyVoucherDuplicate(baseVoucher, differentExpiryVoucher); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: buyerAddress, + }); + }); + + it("should return error if signatures don't match", () => { + const differentSignatureVoucher = { + ...baseVoucher, + signature: + "0x79ce97f6d1242aa7b6f4826efb553ed453fd6c7132c665d95bc226d5f3027dd5456d61ed1bd8da5de6cea4d8154070ff458300b6b84e0c9010f434af77ad3d291c", + }; + + const result = verifyVoucherDuplicate(baseVoucher, differentSignatureVoucher); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + payer: buyerAddress, + }); + }); + + it("should handle case-insensitive ID and signature comparison", () => { + const upperCaseIdVoucher = { + ...baseVoucher, + id: voucherId.toUpperCase(), + signature: voucherSignature.toUpperCase(), + }; + + const resultUpperCase = verifyVoucherDuplicate(baseVoucher, upperCaseIdVoucher); + + expect(resultUpperCase).toEqual({ + isValid: true, + }); + + const lowerCaseIdVoucher = { + ...baseVoucher, + id: voucherId.toLowerCase(), + signature: voucherSignature.toLowerCase(), + }; + + const resultLowerCase = verifyVoucherDuplicate(baseVoucher, lowerCaseIdVoucher); + + expect(resultLowerCase).toEqual({ + isValid: true, + }); + }); + + it("should handle lower case address comparison", () => { + const mixedCaseVoucher = { + ...baseVoucher, + buyer: buyerAddress.toLowerCase(), + seller: sellerAddress.toLowerCase(), + asset: assetAddress.toLowerCase(), + escrow: escrowAddress.toLowerCase(), + }; + + const result = verifyVoucherDuplicate(baseVoucher, mixedCaseVoucher); + + expect(result).toEqual({ + isValid: true, + }); + }); + + it("should handle checksummed address comparison", () => { + const mixedCaseVoucher = { + ...baseVoucher, + escrow: getAddress(escrowAddress), + asset: getAddress(assetAddress), + buyer: getAddress(buyerAddress), + seller: getAddress(sellerAddress), + }; + + const result = verifyVoucherDuplicate(baseVoucher, mixedCaseVoucher); + + expect(result).toEqual({ + isValid: true, + }); + }); }); describe("verifyOnchainState", () => { @@ -373,33 +1131,20 @@ describe("verifyOnchainState", () => { vi.resetAllMocks(); }); - it("should return undefined for valid onchain state", async () => { + it("should return valid if voucher is valid", async () => { vi.mocked(mockClient.readContract) + // outstanding amount .mockResolvedValueOnce([BigInt(1_000_000)]) + // account balance .mockResolvedValueOnce({ balance: BigInt(10_000_000), thawingAmount: BigInt(0), thawEndTime: BigInt(0), }); - const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); - // verifyOnchainState returns { isValid: true } for valid state expect(result).toEqual({ isValid: true }); }); - it("should return error if network is not supported", async () => { - // This test doesn't make sense for verifyOnchainState which doesn't call getNetworkId - // The network check is done in verifyPaymentRequirements - // Updating to test actual behavior - vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); - const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); - expect(result).toEqual({ - isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_outstanding_amount", - payer: buyerAddress, - }); - }); - it("should return error if client network mismatch", async () => { mockClient.chain.id = 1; const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); @@ -434,7 +1179,9 @@ describe("verifyOnchainState", () => { it("should return error if insufficient balance", async () => { vi.mocked(mockClient.readContract) + // outstanding amount .mockResolvedValueOnce([BigInt(1_000_000)]) + // account balance .mockResolvedValueOnce({ balance: BigInt(100_000), thawingAmount: BigInt(0), diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index fd7cbed637..1378b78ec9 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -143,7 +143,7 @@ export function verifyVoucherContinuity( payer: paymentPayload.payload.voucher.buyer, }; } - if (BigInt(voucher.valueAggregate) == 0n) { + if (BigInt(voucher.valueAggregate) === 0n) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_zero_value_aggregate", @@ -180,7 +180,7 @@ export function verifyVoucherContinuity( }; } // valueAggregate - if (voucher.valueAggregate < previousVoucher.valueAggregate) { + if (BigInt(voucher.valueAggregate) < BigInt(previousVoucher.valueAggregate)) { return { isValid: false, invalidReason: "invalid_deferred_evm_payload_voucher_value_aggregate_decreasing", @@ -332,7 +332,7 @@ export function verifyVoucherDuplicate( getAddress(newVoucher.escrow) === getAddress(previousVoucher.escrow) && newVoucher.chainId === previousVoucher.chainId && newVoucher.expiry === previousVoucher.expiry && - newVoucher.signature === previousVoucher.signature + newVoucher.signature.toLowerCase() === previousVoucher.signature.toLowerCase() ) { return { isValid: true, @@ -424,6 +424,7 @@ export async function verifyOnchainState< payer: voucher.buyer, }; } + if (buyerAccount.balance < voucherOutstandingAmount) { return { isValid: false, From f7457151c371639267ff84aff6128d32efc21031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 26 Aug 2025 17:43:46 -0300 Subject: [PATCH 054/116] test: add tests for deferred payment utils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../deferred/evm/utils/paymentUtils.test.ts | 250 ++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts diff --git a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts new file mode 100644 index 0000000000..14be048f71 --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts @@ -0,0 +1,250 @@ +import { describe, expect, it } from "vitest"; +import { encodePayment, decodePayment } from "./paymentUtils"; +import { PaymentPayload } from "../../../../types/verify"; +import { + DeferredPaymentPayload, + DEFERRRED_SCHEME, +} from "../../../../types/verify/schemes/deferred"; + +const buyerAddress = "0xf33332f96E5EA32c90a5301b646Bf5e93EA1D892"; +const sellerAddress = "0x1234567890123456789012345678901234567890"; +const escrowAddress = "0xffffff12345678901234567890123456789fffff"; +const assetAddress = "0x1111111111111111111111111111111111111111"; +const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; +const voucherSignature = + "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c"; + +describe("paymentUtils", () => { + const mockPaymentPayload: DeferredPaymentPayload = { + x402Version: 1, + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + payload: { + signature: voucherSignature, + voucher: { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days + }, + }, + }; + + describe("encodePayment", () => { + it("should encode a deferred payment payload to base64 string", () => { + const encoded = encodePayment(mockPaymentPayload); + + expect(typeof encoded).toBe("string"); + expect(encoded.length).toBeGreaterThan(0); + + // Should be valid base64 + expect(() => { + Buffer.from(encoded, "base64"); + }).not.toThrow(); + }); + + it("should handle vouchers with zero values", () => { + const zeroValuePayload = { + ...mockPaymentPayload, + payload: { + ...mockPaymentPayload.payload, + voucher: { + ...mockPaymentPayload.payload.voucher, + valueAggregate: "0", + timestamp: 0, + nonce: 0, + chainId: 0, + expiry: 0, + }, + }, + }; + + const encoded = encodePayment(zeroValuePayload); + expect(typeof encoded).toBe("string"); + expect(encoded.length).toBeGreaterThan(0); + }); + + it("should throw error for invalid payment payload", () => { + const invalidPayload = { + x402Version: 1, + scheme: "invalid-scheme", + network: "base-sepolia", + } as unknown as PaymentPayload; + + expect(() => encodePayment(invalidPayload)).toThrow(); + }); + + it("should produce consistent encoding for identical inputs", () => { + const encoded1 = encodePayment(mockPaymentPayload); + const encoded2 = encodePayment(mockPaymentPayload); + + expect(encoded1).toBe(encoded2); + }); + }); + + describe("decodePayment", () => { + it("should decode a valid encoded payment payload", () => { + const encoded = encodePayment(mockPaymentPayload); + const decoded = decodePayment(encoded); + + expect(decoded).toEqual(mockPaymentPayload); + }); + + it("should correctly decode voucher fields as expected types", () => { + const encoded = encodePayment(mockPaymentPayload); + const decoded = decodePayment(encoded) as DeferredPaymentPayload; + + expect(typeof decoded.x402Version).toBe("number"); + expect(typeof decoded.scheme).toBe("string"); + expect(typeof decoded.network).toBe("string"); + expect(typeof decoded.payload.signature).toBe("string"); + expect(typeof decoded.payload.voucher.id).toBe("string"); + expect(typeof decoded.payload.voucher.buyer).toBe("string"); + expect(typeof decoded.payload.voucher.seller).toBe("string"); + expect(typeof decoded.payload.voucher.valueAggregate).toBe("string"); + expect(typeof decoded.payload.voucher.asset).toBe("string"); + expect(typeof decoded.payload.voucher.timestamp).toBe("number"); + expect(typeof decoded.payload.voucher.nonce).toBe("number"); + expect(typeof decoded.payload.voucher.escrow).toBe("string"); + expect(typeof decoded.payload.voucher.chainId).toBe("number"); + expect(typeof decoded.payload.voucher.expiry).toBe("number"); + }); + + it("should handle zero values correctly", () => { + const zeroValuePayload = { + ...mockPaymentPayload, + payload: { + ...mockPaymentPayload.payload, + voucher: { + ...mockPaymentPayload.payload.voucher, + valueAggregate: "0", + timestamp: 0, + nonce: 0, + chainId: 0, + expiry: 0, + }, + }, + }; + + const encoded = encodePayment(zeroValuePayload); + const decoded = decodePayment(encoded) as DeferredPaymentPayload; + + expect(decoded.payload.voucher.valueAggregate).toBe("0"); + expect(decoded.payload.voucher.timestamp).toBe(0); + expect(decoded.payload.voucher.nonce).toBe(0); + expect(decoded.payload.voucher.chainId).toBe(0); + expect(decoded.payload.voucher.expiry).toBe(0); + }); + + it("should throw error for invalid base64 string", () => { + const invalidBase64 = "invalid-base64-string!@#"; + + expect(() => decodePayment(invalidBase64)).toThrow(); + }); + + it("should throw error for invalid JSON in base64", () => { + const invalidJson = Buffer.from("invalid json content").toString("base64"); + + expect(() => decodePayment(invalidJson)).toThrow(); + }); + + it("should throw error for valid JSON but invalid payment payload structure", () => { + const invalidPayload = { + x402Version: 1, + scheme: "invalid-scheme", + network: "base-sepolia", + }; + const encoded = Buffer.from(JSON.stringify(invalidPayload)).toString("base64"); + + expect(() => decodePayment(encoded)).toThrow(); + }); + + it("should throw error for malformed voucher data", () => { + const malformedPayload = { + x402Version: 1, + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + payload: { + signature: voucherSignature, + voucher: { + id: voucherId, + // Missing required fields + }, + }, + }; + const encoded = Buffer.from(JSON.stringify(malformedPayload)).toString("base64"); + + expect(() => decodePayment(encoded)).toThrow(); + }); + }); + + describe("round-trip encoding/decoding", () => { + it("should maintain data integrity through multiple encode/decode cycles", () => { + let current = mockPaymentPayload; + + // Perform multiple round trips + for (let i = 0; i < 5; i++) { + const encoded = encodePayment(current); + current = decodePayment(encoded) as DeferredPaymentPayload; + } + + expect(current).toEqual(mockPaymentPayload); + }); + + it("should handle different networks", () => { + const networkTestPayload = { + ...mockPaymentPayload, + network: "iotex" as const, + }; + + const encoded = encodePayment(networkTestPayload); + const decoded = decodePayment(encoded); + + expect(decoded.network).toBe("iotex"); + expect(decoded).toEqual(networkTestPayload); + }); + + it("should handle different signature formats", () => { + const differentSigPayload = { + ...mockPaymentPayload, + payload: { + ...mockPaymentPayload.payload, + signature: "0x" + "0".repeat(130), // Different valid signature format + }, + }; + + const encoded = encodePayment(differentSigPayload); + const decoded = decodePayment(encoded); + + expect(decoded.payload.signature).toBe("0x" + "0".repeat(130)); + expect(decoded).toEqual(differentSigPayload); + }); + + it("should handle voucher with mixed case addresses", () => { + const mixedCasePayload = { + ...mockPaymentPayload, + payload: { + ...mockPaymentPayload.payload, + voucher: { + ...mockPaymentPayload.payload.voucher, + buyer: "0xF33332f96E5EA32c90a5301b646Bf5e93EA1D892", + seller: "0x1234567890123456789012345678901234567890", + asset: "0x1111111111111111111111111111111111111111", + escrow: "0xFFFFFF12345678901234567890123456789FFFFF", + }, + }, + }; + + const encoded = encodePayment(mixedCasePayload); + const decoded = decodePayment(encoded); + + expect(decoded).toEqual(mixedCasePayload); + }); + }); +}); From 5b63422b50f825f4b543cb228fc5cceeb4e36b1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 26 Aug 2025 18:31:29 -0300 Subject: [PATCH 055/116] test: add test coverage for facilitator deferred logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../schemes/deferred/evm/facilitator.test.ts | 553 ++++++++++++++++++ .../x402/src/schemes/deferred/evm/sign.ts | 10 +- 2 files changed, 558 insertions(+), 5 deletions(-) create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts new file mode 100644 index 0000000000..c38b9fca26 --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts @@ -0,0 +1,553 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { Chain, Log, Transport } from "viem"; +import { createSigner, ConnectedClient, SignerWallet } from "../../../types/shared/evm"; +import { PaymentRequirements, SchemeContext } from "../../../types/verify"; +import { DeferredPaymentPayload, DEFERRRED_SCHEME } from "../../../types/verify/schemes/deferred"; +import { verify, settle, settleVoucher } from "./facilitator"; +import { VoucherStore } from "./store"; +import * as verifyModule from "./verify"; + +// Mock the verify module +vi.mock("./verify", () => ({ + verifyPaymentRequirements: vi.fn(), + verifyVoucherContinuity: vi.fn(), + verifyVoucherSignature: vi.fn(), + verifyPreviousVoucherAvailability: vi.fn(), + verifyOnchainState: vi.fn(), +})); + +const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", +); +const buyerAddress = buyer.account.address; +const sellerAddress = "0x1234567890123456789012345678901234567890"; +const escrowAddress = "0xffffff12345678901234567890123456789fffff"; +const assetAddress = "0x1111111111111111111111111111111111111111"; +const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; +const voucherSignature = + "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c"; + +/** + * Mock VoucherStore class for testing + */ +class MockVoucherStore extends VoucherStore { + getVoucher = vi.fn(); + getVoucherSeries = vi.fn(); + getVouchers = vi.fn(); + getAvailableVoucher = vi.fn(); + settleVoucher = vi.fn(); + storeVoucher = vi.fn(); + getVoucherCollections = vi.fn(); +} + +const mockVoucherStore = new MockVoucherStore(); + +describe("facilitator - verify", () => { + const mockVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days + }; + + const mockPaymentPayload: DeferredPaymentPayload = { + x402Version: 1, + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + payload: { + signature: voucherSignature, + voucher: mockVoucher, + }, + }; + + const mockPaymentRequirements: PaymentRequirements = { + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test resource", + mimeType: "application/json", + payTo: sellerAddress, + maxTimeoutSeconds: 300, + asset: assetAddress, + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + }, + }; + + let mockClient: ConnectedClient; + let mockSchemeContext: SchemeContext; + + beforeEach(() => { + vi.clearAllMocks(); + + mockClient = { + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn(), + waitForTransactionReceipt: vi.fn(), + } as unknown as ConnectedClient; + + mockSchemeContext = { + deferred: { + voucherStore: mockVoucherStore, + }, + }; + + // Mock all verification functions to return success by default + vi.mocked(verifyModule.verifyPaymentRequirements).mockReturnValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherContinuity).mockReturnValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyPreviousVoucherAvailability).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it("should return valid response when all verifications pass", async () => { + const result = await verify( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + mockSchemeContext, + ); + + expect(result).toEqual({ + isValid: true, + invalidReason: undefined, + payer: buyerAddress, + }); + }); + + it("should return invalid response when payment requirements verification fails", async () => { + vi.mocked(verifyModule.verifyPaymentRequirements).mockReturnValue({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_scheme", + }); + + const result = await verify( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + mockSchemeContext, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_scheme", + }); + }); + + it("should return invalid response when voucher continuity verification fails", async () => { + vi.mocked(verifyModule.verifyVoucherContinuity).mockReturnValue({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_expired", + payer: buyerAddress, + }); + + const result = await verify( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + mockSchemeContext, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_expired", + payer: buyerAddress, + }); + }); + + it("should return invalid response when voucher signature verification fails", async () => { + vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_signature", + payer: buyerAddress, + }); + + const result = await verify( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + mockSchemeContext, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_signature", + payer: buyerAddress, + }); + }); + + it("should verify previous voucher availability for aggregation type", async () => { + const aggregationRequirements: PaymentRequirements = { + ...mockPaymentRequirements, + extra: { + type: "aggregation", + signature: voucherSignature, + voucher: mockVoucher, + }, + }; + + await verify(mockClient, mockPaymentPayload, aggregationRequirements, mockSchemeContext); + + expect(verifyModule.verifyPreviousVoucherAvailability).toHaveBeenCalledWith( + mockVoucher, + voucherSignature, + mockVoucherStore, + ); + }); + + it("should skip previous voucher verification for new voucher type", async () => { + await verify(mockClient, mockPaymentPayload, mockPaymentRequirements, mockSchemeContext); + + expect(verifyModule.verifyPreviousVoucherAvailability).not.toHaveBeenCalled(); + }); + + it("should return invalid response when onchain state verification fails", async () => { + vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ + isValid: false, + invalidReason: "insufficient_funds", + payer: buyerAddress, + }); + + const result = await verify( + mockClient, + mockPaymentPayload, + mockPaymentRequirements, + mockSchemeContext, + ); + + expect(result).toEqual({ + isValid: false, + invalidReason: "insufficient_funds", + payer: buyerAddress, + }); + }); +}); + +describe("facilitator - settle", () => { + const mockVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + }; + + const mockPaymentPayload: DeferredPaymentPayload = { + x402Version: 1, + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + payload: { + signature: voucherSignature, + voucher: mockVoucher, + }, + }; + + const mockPaymentRequirements: PaymentRequirements = { + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test resource", + mimeType: "application/json", + payTo: sellerAddress, + maxTimeoutSeconds: 300, + asset: assetAddress, + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + }, + }; + + let mockSchemeContext: SchemeContext; + let mockWallet: SignerWallet; + + beforeEach(() => { + vi.clearAllMocks(); + + mockSchemeContext = { + deferred: { + voucherStore: mockVoucherStore, + }, + }; + + // Mock successful verification by default + vi.mocked(verifyModule.verifyPaymentRequirements).mockReturnValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherContinuity).mockReturnValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); + + // Mock successful voucher store settlement + vi.mocked(mockVoucherStore.settleVoucher).mockResolvedValue({ success: true }); + + // Create a proper mock wallet with all required properties + mockWallet = { + account: { + address: buyerAddress, + }, + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn().mockResolvedValue("0x1234567890abcdef"), + waitForTransactionReceipt: vi.fn().mockResolvedValue({ + status: "success", + logs: [ + { + data: "0x000000000000000000000000036cbd53842c5426634e7929541ec2318f3dcf7e0000000000000000000000000000000000000000000000000000000000000050", + topics: [ + "0xfe7c1ad1ce8265245e3420fdcd8d27904701eb6c1d348c3e1704aebfaa8a50e0", + "0x198e73e1cecf59db4fbf8ca10000000000000000000000000000000000000000", + "0x00000000000000000000000080cdf1957ebb7a2df22dd8913753a4423ff4272e", + "0x000000000000000000000000c93d37ad45c907ee1b27a02b2e1bd823ba9d379c", + ], + } as unknown as Log, + ], + }), + } as unknown as SignerWallet; + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it("should settle voucher successfully when all verifications pass", async () => { + const result = await settle( + mockWallet, + mockPaymentPayload, + mockPaymentRequirements, + mockSchemeContext, + ); + + expect(result).toEqual({ + success: true, + network: "base-sepolia", + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + }); + + it("should return error when re-verification fails", async () => { + vi.mocked(verifyModule.verifyPaymentRequirements).mockReturnValue({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_scheme", + }); + + const result = await settle( + buyer, + mockPaymentPayload, + mockPaymentRequirements, + mockSchemeContext, + ); + + expect(result).toEqual({ + success: false, + network: "base-sepolia", + transaction: "", + errorReason: "invalid_deferred_evm_payload_scheme", + payer: buyerAddress, + }); + }); +}); + +describe("facilitator - settleVoucher", () => { + const mockVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + }; + + let mockVoucherStore: VoucherStore; + let mockWallet: SignerWallet; + + beforeEach(() => { + vi.clearAllMocks(); + + mockVoucherStore = { + settleVoucher: vi.fn().mockResolvedValue({ success: true }), + } as unknown as VoucherStore; + + // Mock successful verification by default + vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); + + // Mock successful voucher store settlement + vi.mocked(mockVoucherStore.settleVoucher).mockResolvedValue({ success: true }); + + // Create a proper mock wallet with all required properties + mockWallet = { + account: { + address: buyerAddress, + }, + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn().mockResolvedValue("0x1234567890abcdef"), + waitForTransactionReceipt: vi.fn().mockResolvedValue({ + status: "success", + logs: [ + { + data: "0x000000000000000000000000036cbd53842c5426634e7929541ec2318f3dcf7e0000000000000000000000000000000000000000000000000000000000000050", + topics: [ + "0xfe7c1ad1ce8265245e3420fdcd8d27904701eb6c1d348c3e1704aebfaa8a50e0", + "0x198e73e1cecf59db4fbf8ca10000000000000000000000000000000000000000", + "0x00000000000000000000000080cdf1957ebb7a2df22dd8913753a4423ff4272e", + "0x000000000000000000000000c93d37ad45c907ee1b27a02b2e1bd823ba9d379c", + ], + } as unknown as Log, + ], + }), + } as unknown as SignerWallet; + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it("should settle voucher successfully", async () => { + const result = await settleVoucher(mockWallet, mockVoucher, voucherSignature, mockVoucherStore); + + expect(result).toEqual({ + success: true, + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + + expect(mockVoucherStore.settleVoucher).toHaveBeenCalledWith( + mockVoucher, + "0x1234567890abcdef", + 0n, // mocked amount in log + ); + }); + + it("should return error when voucher signature verification fails", async () => { + vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_signature", + }); + + const result = await settleVoucher(mockWallet, mockVoucher, voucherSignature, mockVoucherStore); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_deferred_evm_payload_signature", + transaction: "", + payer: buyerAddress, + }); + }); + + it("should return error when onchain state verification fails", async () => { + vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ + isValid: false, + invalidReason: "insufficient_funds", + }); + + const result = await settleVoucher(buyer, mockVoucher, voucherSignature, mockVoucherStore); + + expect(result).toEqual({ + success: false, + errorReason: "insufficient_funds", + transaction: "", + payer: buyerAddress, + }); + }); + + it("should return error when contract transaction fails", async () => { + mockWallet.writeContract = vi.fn().mockRejectedValue(new Error("Transaction failed")); + + const result = await settleVoucher(mockWallet, mockVoucher, voucherSignature, mockVoucherStore); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_transaction_reverted", + transaction: "", + payer: buyerAddress, + }); + }); + + it("should return error when transaction receipt shows failure", async () => { + mockWallet.waitForTransactionReceipt = vi.fn().mockResolvedValue({ + status: "reverted", + logs: [], + }); + + const result = await settleVoucher(mockWallet, mockVoucher, voucherSignature, mockVoucherStore); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_transaction_state", + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + }); + + it("should return error when voucher store settlement fails", async () => { + vi.mocked(mockVoucherStore.settleVoucher).mockResolvedValue({ success: false }); + + const result = await settleVoucher(mockWallet, mockVoucher, voucherSignature, mockVoucherStore); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_deferred_evm_payload_voucher_could_not_settle_store", + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + }); + + it("should return error when voucher store throws exception", async () => { + vi.mocked(mockVoucherStore.settleVoucher).mockRejectedValue(new Error("Store error")); + + const result = await settleVoucher(mockWallet, mockVoucher, voucherSignature, mockVoucherStore); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_deferred_evm_payload_voucher_error_settling_store", + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + }); + + it("should handle empty logs when parsing voucher collected event", async () => { + mockWallet.waitForTransactionReceipt = vi.fn().mockResolvedValue({ + status: "success", + logs: [], + }); + + const result = await settleVoucher(mockWallet, mockVoucher, voucherSignature, mockVoucherStore); + + expect(result.success).toBe(true); + expect(mockVoucherStore.settleVoucher).toHaveBeenCalledWith( + mockVoucher, + "0x1234567890abcdef", + 0n, // Default amount when no logs + ); + }); +}); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts index df1e293835..f2d2b5c5fc 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts @@ -31,14 +31,14 @@ export async function signVoucher Date: Wed, 27 Aug 2025 11:17:28 -0300 Subject: [PATCH 056/116] feat: add deferred server helper with test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/schemes/deferred/evm/index.ts | 1 + .../src/schemes/deferred/evm/server.test.ts | 322 ++++++++++++++++++ .../x402/src/schemes/deferred/evm/server.ts | 67 ++++ 3 files changed, 390 insertions(+) create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/server.test.ts create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/server.ts diff --git a/typescript/packages/x402/src/schemes/deferred/evm/index.ts b/typescript/packages/x402/src/schemes/deferred/evm/index.ts index f675efa745..e5f1e203a1 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/index.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/index.ts @@ -1,6 +1,7 @@ export * from "./client"; export * from "./facilitator"; export * from "./id"; +export * from "./server"; export * from "./sign"; export * from "./store"; export * from "./utils/paymentUtils"; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/server.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/server.test.ts new file mode 100644 index 0000000000..450c73179c --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/server.test.ts @@ -0,0 +1,322 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { Address, getAddress } from "viem"; +import { + DeferredEvmPayloadSignedVoucher, + DeferredPaymentRequirements, + PaymentPayload, +} from "../../../types"; +import { getPaymentRequirementsExtra } from "./server"; +import * as idModule from "./id"; +import * as paymentUtilsModule from "./utils/paymentUtils"; + +// Mock dependencies +vi.mock("./id", () => ({ + generateVoucherId: vi.fn(), +})); + +vi.mock("./utils/paymentUtils", () => ({ + decodePayment: vi.fn(), +})); + +describe("getPaymentRequirementsExtra", () => { + const mockSeller: Address = "0x1234567890123456789012345678901234567890"; + const mockEscrow: Address = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"; + const mockBuyer: Address = "0x9876543210987654321098765432109876543210"; + const mockVoucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; + const mockSignature = + "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c"; + + const mockVoucher = { + id: mockVoucherId, + buyer: mockBuyer, + seller: mockSeller, + valueAggregate: "1000000", + asset: "0x1111111111111111111111111111111111111111", + timestamp: 1715769600, + nonce: 5, + escrow: mockEscrow, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: mockSignature, + }; + + const mockGetAvailableVoucher = vi.fn(); + + beforeEach(() => { + vi.clearAllMocks(); + vi.mocked(idModule.generateVoucherId).mockReturnValue(mockVoucherId); + }); + + describe("when no headers are provided", () => { + it("should return a new voucher extra", async () => { + const result = await getPaymentRequirementsExtra( + undefined, + undefined, + mockSeller, + mockEscrow, + mockGetAvailableVoucher, + ); + + expect(result).toEqual({ + type: "new", + voucher: { + id: mockVoucherId, + escrow: mockEscrow, + }, + }); + + expect(mockGetAvailableVoucher).not.toHaveBeenCalled(); + expect(idModule.generateVoucherId).toHaveBeenCalledOnce(); + }); + }); + + describe("when only X-BUYER header is provided", () => { + it("should return aggregation extra when previous voucher exists", async () => { + mockGetAvailableVoucher.mockResolvedValue(mockVoucher); + + const result = await getPaymentRequirementsExtra( + undefined, + mockBuyer, + mockSeller, + mockEscrow, + mockGetAvailableVoucher, + ); + + expect(result).toEqual({ + type: "aggregation", + signature: mockSignature, + voucher: mockVoucher, + }); + + expect(mockGetAvailableVoucher).toHaveBeenCalledWith(mockBuyer, mockSeller); + expect(mockGetAvailableVoucher).toHaveBeenCalledOnce(); + }); + + it("should return new voucher extra when no previous voucher exists", async () => { + mockGetAvailableVoucher.mockResolvedValue(null); + + const result = await getPaymentRequirementsExtra( + undefined, + mockBuyer, + mockSeller, + mockEscrow, + mockGetAvailableVoucher, + ); + + expect(result).toEqual({ + type: "new", + voucher: { + id: mockVoucherId, + escrow: mockEscrow, + }, + }); + + expect(mockGetAvailableVoucher).toHaveBeenCalledWith(mockBuyer, mockSeller); + }); + }); + + describe("when only X-PAYMENT header is provided", () => { + const mockPaymentHeader = "base64encodedheader"; + + it("should return aggregation extra when payment header is valid and previous voucher exists", async () => { + vi.mocked(paymentUtilsModule.decodePayment).mockReturnValue({ + x402Version: 1, + scheme: "deferred", + network: "base-sepolia", + payload: { + signature: mockSignature, + voucher: mockVoucher, + }, + }); + + mockGetAvailableVoucher.mockResolvedValue(mockVoucher); + + const result = await getPaymentRequirementsExtra( + mockPaymentHeader, + undefined, + mockSeller, + mockEscrow, + mockGetAvailableVoucher, + ); + + expect(result).toEqual({ + type: "aggregation", + signature: mockSignature, + voucher: mockVoucher, + }); + + expect(paymentUtilsModule.decodePayment).toHaveBeenCalledWith(mockPaymentHeader); + expect(mockGetAvailableVoucher).toHaveBeenCalledWith(mockBuyer, mockSeller); + }); + + it("should return new voucher extra when payment header is invalid", async () => { + vi.mocked(paymentUtilsModule.decodePayment).mockReturnValue({ + x402Version: 1, + scheme: "deferred", + network: "base-sepolia", + payload: { + invalidField: "invalid", + }, + } as unknown as PaymentPayload); + + const result = await getPaymentRequirementsExtra( + mockPaymentHeader, + undefined, + mockSeller, + mockEscrow, + mockGetAvailableVoucher, + ); + + expect(result).toEqual({ + type: "new", + voucher: { + id: mockVoucherId, + escrow: mockEscrow, + }, + }); + + expect(paymentUtilsModule.decodePayment).toHaveBeenCalledWith(mockPaymentHeader); + expect(mockGetAvailableVoucher).not.toHaveBeenCalled(); + }); + + it("should return new voucher extra when payment header is valid but no previous voucher exists", async () => { + vi.mocked(paymentUtilsModule.decodePayment).mockReturnValue({ + x402Version: 1, + scheme: "deferred", + network: "base-sepolia", + payload: { + signature: mockSignature, + voucher: mockVoucher, + }, + }); + + mockGetAvailableVoucher.mockResolvedValue(null); + + const result = await getPaymentRequirementsExtra( + mockPaymentHeader, + undefined, + mockSeller, + mockEscrow, + mockGetAvailableVoucher, + ); + + expect(result).toEqual({ + type: "new", + voucher: { + id: mockVoucherId, + escrow: mockEscrow, + }, + }); + + expect(mockGetAvailableVoucher).toHaveBeenCalledWith(mockBuyer, mockSeller); + }); + }); + + describe("when both headers are provided", () => { + it("should prioritize X-PAYMENT header over X-BUYER header", async () => { + const differentBuyer: Address = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; + + vi.mocked(paymentUtilsModule.decodePayment).mockReturnValue({ + x402Version: 1, + scheme: "deferred", + network: "base-sepolia", + payload: { + signature: mockSignature, + voucher: { + ...mockVoucher, + buyer: differentBuyer, + }, + }, + }); + + const voucherResponse: DeferredEvmPayloadSignedVoucher = { + ...mockVoucher, + buyer: differentBuyer, + }; + mockGetAvailableVoucher.mockResolvedValue(voucherResponse); + + const result = await getPaymentRequirementsExtra( + "paymentHeader", + mockBuyer, // This should be ignored + mockSeller, + mockEscrow, + mockGetAvailableVoucher, + ); + + expect(result).toEqual({ + type: "aggregation", + signature: mockSignature, + voucher: { + ...mockVoucher, + buyer: differentBuyer, + }, + }); + + // Should use buyer from payment header, not from X-BUYER header + // getAddress normalizes the address to checksum format + expect(mockGetAvailableVoucher).toHaveBeenCalledWith(getAddress(differentBuyer), mockSeller); + expect(mockGetAvailableVoucher).not.toHaveBeenCalledWith(mockBuyer, mockSeller); + }); + }); + + describe("edge cases", () => { + it("should handle getAvailableVoucher throwing an error", async () => { + mockGetAvailableVoucher.mockRejectedValue(new Error("Database error")); + + await expect( + getPaymentRequirementsExtra( + undefined, + mockBuyer, + mockSeller, + mockEscrow, + mockGetAvailableVoucher, + ), + ).rejects.toThrow("Database error"); + }); + + it("should handle decodePayment throwing an error", async () => { + vi.mocked(paymentUtilsModule.decodePayment).mockImplementation(() => { + throw new Error("Invalid base64"); + }); + + await expect( + getPaymentRequirementsExtra( + "invalid-header", + undefined, + mockSeller, + mockEscrow, + mockGetAvailableVoucher, + ), + ).rejects.toThrow("Invalid base64"); + }); + + it("should generate unique voucher IDs for each new voucher request", async () => { + const voucherId1 = "0x1111111111111111111111111111111111111111111111111111111111111111"; + const voucherId2 = "0x2222222222222222222222222222222222222222222222222222222222222222"; + + vi.mocked(idModule.generateVoucherId) + .mockReturnValueOnce(voucherId1) + .mockReturnValueOnce(voucherId2); + + const result1 = (await getPaymentRequirementsExtra( + undefined, + undefined, + mockSeller, + mockEscrow, + mockGetAvailableVoucher, + )) as DeferredPaymentRequirements["extra"]; + + const result2 = (await getPaymentRequirementsExtra( + undefined, + undefined, + mockSeller, + mockEscrow, + mockGetAvailableVoucher, + )) as DeferredPaymentRequirements["extra"]; + + expect(result1.voucher.id).toBe(voucherId1); + expect(result2.voucher.id).toBe(voucherId2); + expect(result1.voucher.id).not.toBe(result2.voucher.id); + }); + }); +}); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/server.ts b/typescript/packages/x402/src/schemes/deferred/evm/server.ts new file mode 100644 index 0000000000..842aa96ea3 --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/server.ts @@ -0,0 +1,67 @@ +import { Address, getAddress } from "viem"; +import { + DeferredEvmPayloadSchema, + DeferredEvmPayloadSignedVoucher, + PaymentRequirementsExtra, +} from "../../../types"; +import { generateVoucherId } from "./id"; +import { decodePayment } from "./utils/paymentUtils"; + +/** + * Compute the extra data for the payment requirements + * + * @param xPaymentHeader - The x-payment header + * @param xBuyerHeader - The x-buyer header + * @param seller - The seller address + * @param escrow - The escrow address + * @param getAvailableVoucher - A function to get the latest voucher for a given buyer and seller. + * @returns The extra data for the payment requirements + */ +export async function getPaymentRequirementsExtra( + xPaymentHeader: string | undefined, + xBuyerHeader: Address | undefined, + seller: Address, + escrow: Address, + getAvailableVoucher: ( + buyer: string, + seller: string, + ) => Promise, +): Promise { + let buyer: Address; + const newVoucherExtra = { + type: "new" as const, + voucher: { + id: generateVoucherId(), + escrow, + }, + }; + + // No headers -> new voucher + if (!xPaymentHeader && !xBuyerHeader) { + return newVoucherExtra; + } + + // Extract buyer from X-PAYMENT or X-BUYER header + if (xPaymentHeader) { + const paymentHeader = decodePayment(xPaymentHeader); + const parsedPaymentPayload = DeferredEvmPayloadSchema.safeParse(paymentHeader.payload); + if (!parsedPaymentPayload.success) { + return newVoucherExtra; + } + buyer = getAddress(parsedPaymentPayload.data.voucher.buyer); + } else { + buyer = xBuyerHeader!; // This is safe due to the previous early return + } + + const previousVoucher = await getAvailableVoucher(buyer, seller); + if (previousVoucher) { + return { + type: "aggregation" as const, + signature: previousVoucher.signature, + voucher: { + ...previousVoucher, + }, + }; + } + return newVoucherExtra; +} From 5f54c8f15c656d9055b4ccefaae0a60420816c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 27 Aug 2025 11:36:29 -0300 Subject: [PATCH 057/116] fix: ensure voucher exists in store before settling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/facilitator.test.ts | 14 ++++++++++++++ .../x402/src/schemes/deferred/evm/facilitator.ts | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts index c38b9fca26..9df79b571e 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts @@ -303,6 +303,7 @@ describe("facilitator - settle", () => { // Mock successful voucher store settlement vi.mocked(mockVoucherStore.settleVoucher).mockResolvedValue({ success: true }); + vi.mocked(mockVoucherStore.getVoucher).mockResolvedValue(mockVoucher); // Create a proper mock wallet with all required properties mockWallet = { @@ -394,6 +395,7 @@ describe("facilitator - settleVoucher", () => { mockVoucherStore = { settleVoucher: vi.fn().mockResolvedValue({ success: true }), + getVoucher: vi.fn().mockResolvedValue(mockVoucher), } as unknown as VoucherStore; // Mock successful verification by default @@ -448,6 +450,18 @@ describe("facilitator - settleVoucher", () => { ); }); + it("should return error when voucher not found in store", async () => { + vi.mocked(mockVoucherStore.getVoucher).mockResolvedValue(null); + const result = await settleVoucher(mockWallet, mockVoucher, voucherSignature, mockVoucherStore); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_deferred_evm_payload_voucher_voucher_not_found", + transaction: "", + payer: buyerAddress, + }); + }); + it("should return error when voucher signature verification fails", async () => { vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ isValid: false, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 41569bf0c6..5f64dcf76b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -174,6 +174,17 @@ export async function settleVoucher Date: Wed, 27 Aug 2025 11:38:16 -0300 Subject: [PATCH 058/116] chore: add missing error definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/types/verify/schemes/deferred.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 2177ecc6bd..8be349f3de 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -42,6 +42,7 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_voucher_not_duplicate", "invalid_deferred_evm_payload_voucher_could_not_settle_store", "invalid_deferred_evm_payload_voucher_error_settling_store", + "invalid_deferred_evm_payload_voucher_voucher_not_found", ] as const; // x402DeferredEvmPayloadVoucher From 5e2e57234201be835934db3daebd55bb530fdddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 27 Aug 2025 15:02:26 -0300 Subject: [PATCH 059/116] test: add integration tests, fix several bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../schemes/deferred/evm/facilitator.test.ts | 27 +- .../src/schemes/deferred/evm/facilitator.ts | 20 +- .../schemes/deferred/evm/integration.test.ts | 460 ++++++++++++++++++ .../src/schemes/deferred/evm/store.mock.ts | 214 ++++++++ .../x402/src/schemes/deferred/evm/store.ts | 2 - .../src/schemes/deferred/evm/verify.test.ts | 28 +- .../x402/src/schemes/deferred/evm/verify.ts | 21 +- .../x402/src/types/verify/schemes/deferred.ts | 4 +- 8 files changed, 747 insertions(+), 29 deletions(-) create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts create mode 100644 typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts index 9df79b571e..4696328d25 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts @@ -12,7 +12,7 @@ vi.mock("./verify", () => ({ verifyPaymentRequirements: vi.fn(), verifyVoucherContinuity: vi.fn(), verifyVoucherSignature: vi.fn(), - verifyPreviousVoucherAvailability: vi.fn(), + verifyVoucherAvailability: vi.fn(), verifyOnchainState: vi.fn(), })); @@ -109,7 +109,7 @@ describe("facilitator - verify", () => { vi.mocked(verifyModule.verifyPaymentRequirements).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherContinuity).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ isValid: true }); - vi.mocked(verifyModule.verifyPreviousVoucherAvailability).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); }); @@ -205,9 +205,11 @@ describe("facilitator - verify", () => { await verify(mockClient, mockPaymentPayload, aggregationRequirements, mockSchemeContext); - expect(verifyModule.verifyPreviousVoucherAvailability).toHaveBeenCalledWith( + expect(verifyModule.verifyVoucherAvailability).toHaveBeenCalledWith( mockVoucher, voucherSignature, + mockVoucher.id, + mockVoucher.nonce, // mockVoucher is the previous voucher mockVoucherStore, ); }); @@ -215,7 +217,7 @@ describe("facilitator - verify", () => { it("should skip previous voucher verification for new voucher type", async () => { await verify(mockClient, mockPaymentPayload, mockPaymentRequirements, mockSchemeContext); - expect(verifyModule.verifyPreviousVoucherAvailability).not.toHaveBeenCalled(); + expect(verifyModule.verifyVoucherAvailability).not.toHaveBeenCalled(); }); it("should return invalid response when onchain state verification fails", async () => { @@ -300,6 +302,7 @@ describe("facilitator - settle", () => { vi.mocked(verifyModule.verifyVoucherContinuity).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); // Mock successful voucher store settlement vi.mocked(mockVoucherStore.settleVoucher).mockResolvedValue({ success: true }); @@ -401,6 +404,7 @@ describe("facilitator - settleVoucher", () => { // Mock successful verification by default vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); // Mock successful voucher store settlement vi.mocked(mockVoucherStore.settleVoucher).mockResolvedValue({ success: true }); @@ -451,12 +455,23 @@ describe("facilitator - settleVoucher", () => { }); it("should return error when voucher not found in store", async () => { - vi.mocked(mockVoucherStore.getVoucher).mockResolvedValue(null); + vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_not_found", + }); + const result = await settleVoucher(mockWallet, mockVoucher, voucherSignature, mockVoucherStore); + expect(verifyModule.verifyVoucherAvailability).toHaveBeenCalledWith( + mockVoucher, + voucherSignature, + mockVoucher.id, + mockVoucher.nonce, + mockVoucherStore, + ); expect(result).toEqual({ success: false, - errorReason: "invalid_deferred_evm_payload_voucher_voucher_not_found", + errorReason: "invalid_deferred_evm_payload_voucher_not_found", transaction: "", payer: buyerAddress, }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 5f64dcf76b..3983194b6f 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -19,7 +19,7 @@ import { verifyVoucherSignature, verifyOnchainState, verifyVoucherContinuity, - verifyPreviousVoucherAvailability, + verifyVoucherAvailability, } from "./verify"; import { VoucherStore } from "./store"; @@ -76,9 +76,11 @@ export async function verify< // Verify previous voucher availability if (paymentRequirements.extra.type === "aggregation") { - const previousVoucherResult = await verifyPreviousVoucherAvailability( + const previousVoucherResult = await verifyVoucherAvailability( paymentRequirements.extra.voucher, paymentRequirements.extra.signature, + paymentRequirements.extra.voucher.id, + paymentRequirements.extra.voucher.nonce, voucherStore, ); if (!previousVoucherResult.isValid) { @@ -122,8 +124,8 @@ export async function settle( const { voucherStore } = DeferredSchemeContextSchema.parse(schemeContext.deferred); // re-verify to ensure the payment is still valid + // TODO: there is some verification duplication as some of the verification steps are repeated later when calling settleVoucher const valid = await verify(wallet, paymentPayload, paymentRequirements, schemeContext); - if (!valid.isValid) { return { success: false, @@ -175,11 +177,17 @@ export async function settleVoucher { + const sellerAddress = "0x1234567890123456789012345678901234567890"; + const escrowAddress = "0xffffff12345678901234567890123456789fffff"; + const assetAddress = "0x1111111111111111111111111111111111111111"; + + const baseVoucher = { + id: "0x9dce748efdc0ac6ce5875ae50b7cb8aff28d14e4f335b4f6393c2ed3866bc361", + buyer: "0x05159b6100E8c7A3BbaE174A94c32E1E2e37059b", + seller: "0x1234567890123456789012345678901234567890", + valueAggregate: "1017", + asset: "0x1111111111111111111111111111111111111111", + timestamp: 1756313313, + nonce: 0, + escrow: "0xffFfFf12345678901234567890123456789fffFF", + chainId: 84532, + expiry: 1758905313, + signature: + "0x3921aa078a4d02b2c7f65614a87636a7e62f9d3990842204cf778c92a7721dba54831c2269df2ef84231d79680f844a81b7aba33a8482dfa7e97a71cf613c66f1b", + }; + const basePaymentRequirements = { + scheme: DEFERRRED_SCHEME, + network: "base-sepolia", + maxAmountRequired: "1017", + resource: "https://example.com/resource", + description: "payment", + mimeType: "application/json", + payTo: sellerAddress, + maxTimeoutSeconds: 300, + asset: assetAddress, + }; + + beforeAll(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date(baseVoucher.timestamp * 1000 + 1000)); + }); + + afterAll(() => { + vi.useRealTimers(); + }); + + describe("End-to-end x402 payment flow: /verify, /settle", () => { + it("should handle complete payment lifecycle with client initiating with buyer address and no previous history", async () => { + // Initialize facilitator -- we use in memory voucher store but blockchain interactions are mocked + const voucherStore = new InMemoryVoucherStore(); + const facilitatorWallet = { + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn(), + waitForTransactionReceipt: vi.fn(), + } as unknown as SignerWallet; + + // * Step 1: Payment requirements generation + // Buyer client requests access to a resource specifying their address via X-BUYER header + const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + + // Seller middleware decodes X-BUYER header and generates payment requirements + const buyerAddress = buyer.account.address; + const paymentRequirements = { + ...basePaymentRequirements, + extra: await getPaymentRequirementsExtra( + undefined, // no X-PAYMENT header -- client initiates with X-BUYER header + buyerAddress, + sellerAddress, + escrowAddress, + (buyer, seller) => voucherStore.getAvailableVoucher(buyer, seller), + ), + } as DeferredPaymentRequirements; + + expect(paymentRequirements.extra.type).toBe("new"); + + // * Step 2: Payment payload generation + // Buyer creates a new signed voucher, encodes it as X-PAYMENT header and sends it to the seller + const paymentPayload = await createPaymentHeader(buyer, 1, paymentRequirements); + + // * Step 3: Seller decodes and verifies the payment payload, then stores the voucher in the store - mock blockchain interactions + const decodedPaymentPayload = decodePayment(paymentPayload) as DeferredPaymentPayload; + mockBlockchainInteractionsVerify(facilitatorWallet); + const verifyResponse = await verify( + facilitatorWallet, + decodedPaymentPayload, + paymentRequirements, + { + deferred: { voucherStore }, + }, + ); + expect(verifyResponse.isValid).toBe(true); + + const signedVoucher = { + ...decodedPaymentPayload.payload.voucher, + signature: decodedPaymentPayload.payload.signature, + }; + voucherStore.storeVoucher(signedVoucher); + const storedVoucher = await voucherStore.getVoucher( + decodedPaymentPayload.payload.voucher.id, + decodedPaymentPayload.payload.voucher.nonce, + ); + expect(voucherStore.vouchers.length).toBe(1); + expect(signedVoucher).toEqual(storedVoucher); + + // * Step 4: Seller does work + // -- Nothing to do here -- + + // * Step 5: Seller settles the voucher -- mock blockchain interactions + mockBlockchainInteractionsSettle(facilitatorWallet); + const settleResponse = await settle( + facilitatorWallet, + decodedPaymentPayload, + paymentRequirements, + { deferred: { voucherStore } }, + ); + expect(settleResponse.success).toBe(true); + + const voucherCollections = await voucherStore.getVoucherCollections( + decodedPaymentPayload.payload.voucher.id, + decodedPaymentPayload.payload.voucher.nonce, + ); + expect(voucherCollections.length).toBe(1); + expect(voucherCollections[0]).toEqual({ + voucherId: decodedPaymentPayload.payload.voucher.id, + voucherNonce: decodedPaymentPayload.payload.voucher.nonce, + chainId: decodedPaymentPayload.payload.voucher.chainId, + transactionHash: settleResponse.transaction, + collectedAmount: decodedPaymentPayload.payload.voucher.valueAggregate, + asset: decodedPaymentPayload.payload.voucher.asset, + collectedAt: expect.any(Number), + }); + }); + + it("should handle complete payment lifecycle with client initiating with buyer address and previous history", async () => { + // Initialize facilitator -- we use in memory voucher store but blockchain interactions are mocked + const voucherStore = new InMemoryVoucherStore(); + voucherStore.storeVoucher(baseVoucher); + const facilitatorWallet = { + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn(), + waitForTransactionReceipt: vi.fn(), + } as unknown as SignerWallet; + + // * Step 1: Payment requirements generation + // Buyer client requests access to a resource specifying their address via X-BUYER header + const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + + // Seller middleware decodes X-BUYER header and generates payment requirements + const buyerAddress = buyer.account.address; + const paymentRequirements = { + ...basePaymentRequirements, + extra: await getPaymentRequirementsExtra( + undefined, // no X-PAYMENT header -- client initiates with X-BUYER header + buyerAddress, + sellerAddress, + escrowAddress, + (buyer, seller) => voucherStore.getAvailableVoucher(buyer, seller), + ), + } as DeferredPaymentRequirements; + + expect(paymentRequirements.extra.type).toBe("aggregation"); + + // * Step 2: Payment payload generation + // Buyer creates a new signed voucher, encodes it as X-PAYMENT header and sends it to the seller + const paymentPayload = await createPaymentHeader(buyer, 1, paymentRequirements); + + // * Step 3: Seller decodes and verifies the payment payload, then stores the voucher in the store - mock blockchain interactions + const decodedPaymentPayload = decodePayment(paymentPayload) as DeferredPaymentPayload; + mockBlockchainInteractionsVerify(facilitatorWallet); + const verifyResponse = await verify( + facilitatorWallet, + decodedPaymentPayload, + paymentRequirements, + { + deferred: { voucherStore }, + }, + ); + expect(verifyResponse.isValid).toBe(true); + + voucherStore.storeVoucher({ + ...decodedPaymentPayload.payload.voucher, + signature: decodedPaymentPayload.payload.signature, + }); + expect(voucherStore.vouchers.length).toBe(2); + expect( + await voucherStore.getVoucher( + decodedPaymentPayload.payload.voucher.id, + decodedPaymentPayload.payload.voucher.nonce, + ), + ).toEqual({ + ...decodedPaymentPayload.payload.voucher, + signature: decodedPaymentPayload.payload.signature, + }); + + // * Step 4: Seller does work + // -- Nothing to do here -- + + // * Step 5: Seller settles the voucher -- mock blockchain interactions + mockBlockchainInteractionsSettle(facilitatorWallet); + const settleResponse = await settle( + facilitatorWallet, + decodedPaymentPayload, + paymentRequirements, + { deferred: { voucherStore } }, + ); + expect(settleResponse.success).toBe(true); + + const voucherCollections = await voucherStore.getVoucherCollections( + decodedPaymentPayload.payload.voucher.id, + decodedPaymentPayload.payload.voucher.nonce, + ); + expect(voucherCollections.length).toBe(1); + expect(voucherCollections[0]).toEqual({ + voucherId: decodedPaymentPayload.payload.voucher.id, + voucherNonce: decodedPaymentPayload.payload.voucher.nonce, + chainId: decodedPaymentPayload.payload.voucher.chainId, + transactionHash: settleResponse.transaction, + collectedAmount: baseVoucher.valueAggregate, // mocked transaction data uses the base voucher valueAggregate + asset: decodedPaymentPayload.payload.voucher.asset, + collectedAt: expect.any(Number), + }); + }); + + it("should handle complete payment lifecycle with client initiating with payment payload and previous history", async () => { + // Initialize facilitator -- we use in memory voucher store but blockchain interactions are mocked + const voucherStore = new InMemoryVoucherStore(); + voucherStore.storeVoucher(baseVoucher); + const facilitatorWallet = { + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn(), + waitForTransactionReceipt: vi.fn(), + } as unknown as SignerWallet; + + // * Step 0: Payment payload generation + // Buyer has the previous payment requirements so they can generate the new ones directly, skipping the X-BUYER header + const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const buyerAddress = buyer.account.address; + const originalPaymentRequirements = { + ...basePaymentRequirements, + extra: await getPaymentRequirementsExtra( + undefined, // no X-PAYMENT header -- client initiates with X-BUYER header + buyerAddress, + sellerAddress, + escrowAddress, + (buyer, seller) => voucherStore.getAvailableVoucher(buyer, seller), + ), + } as DeferredPaymentRequirements; + const originalPaymentPayload = await createPaymentHeader( + buyer, + 1, + originalPaymentRequirements, + ); + + // * Step 1: Payment requirements generation + // Seller middleware decodes X-PAYMENT header and generates payment requirements + const paymentRequirements = { + ...basePaymentRequirements, + extra: await getPaymentRequirementsExtra( + originalPaymentPayload, // X-PAYMENT present! -- client initiates with X-PAYMENT header + undefined, // no X-BUYER header + sellerAddress, + escrowAddress, + (buyer, seller) => voucherStore.getAvailableVoucher(buyer, seller), + ), + } as DeferredPaymentRequirements; + + expect(paymentRequirements.extra.type).toBe("aggregation"); + + // * Step 2: Payment payload generation + // Buyer creates a new signed voucher, encodes it as X-PAYMENT header and sends it to the seller + const paymentPayload = await createPaymentHeader(buyer, 1, paymentRequirements); + + // * Step 3: Seller decodes and verifies the payment payload, then stores the voucher in the store - mock blockchain interactions + const decodedPaymentPayload = decodePayment(paymentPayload) as DeferredPaymentPayload; + mockBlockchainInteractionsVerify(facilitatorWallet); + const verifyResponse = await verify( + facilitatorWallet, + decodedPaymentPayload, + paymentRequirements, + { + deferred: { voucherStore }, + }, + ); + expect(verifyResponse.isValid).toBe(true); + + voucherStore.storeVoucher({ + ...decodedPaymentPayload.payload.voucher, + signature: decodedPaymentPayload.payload.signature, + }); + expect(voucherStore.vouchers.length).toBe(2); + expect( + await voucherStore.getVoucher( + decodedPaymentPayload.payload.voucher.id, + decodedPaymentPayload.payload.voucher.nonce, + ), + ).toEqual({ + ...decodedPaymentPayload.payload.voucher, + signature: decodedPaymentPayload.payload.signature, + }); + + // * Step 4: Seller does work + // -- Nothing to do here -- + + // * Step 5: Seller settles the voucher -- mock blockchain interactions + mockBlockchainInteractionsSettle(facilitatorWallet); + const settleResponse = await settle( + facilitatorWallet, + decodedPaymentPayload, + paymentRequirements, + { deferred: { voucherStore } }, + ); + expect(settleResponse.success).toBe(true); + + const voucherCollections = await voucherStore.getVoucherCollections( + decodedPaymentPayload.payload.voucher.id, + decodedPaymentPayload.payload.voucher.nonce, + ); + expect(voucherCollections.length).toBe(1); + expect(voucherCollections[0]).toEqual({ + voucherId: decodedPaymentPayload.payload.voucher.id, + voucherNonce: decodedPaymentPayload.payload.voucher.nonce, + chainId: decodedPaymentPayload.payload.voucher.chainId, + transactionHash: settleResponse.transaction, + collectedAmount: baseVoucher.valueAggregate, // mocked transaction data uses the base voucher valueAggregate + asset: decodedPaymentPayload.payload.voucher.asset, + collectedAt: expect.any(Number), + }); + }); + }); + + describe("Multi-round voucher aggregation", () => { + it("should support multiple rounds of aggregation", async () => { + const voucherStore = new InMemoryVoucherStore(); + const facilitatorWallet = { + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn(), + waitForTransactionReceipt: vi.fn(), + } as unknown as SignerWallet; + + const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const paymentRequirements = { + ...basePaymentRequirements, + maxAmountRequired: "100000", + extra: { + type: "new", + voucher: baseVoucher, + }, + } as DeferredPaymentRequirements; + const firstPaymentPayload = (await createPayment( + buyer, + 1, + paymentRequirements, + )) as DeferredPaymentPayload; + voucherStore.storeVoucher({ + ...firstPaymentPayload.payload.voucher, + signature: firstPaymentPayload.payload.signature, + }); + + mockBlockchainInteractionsVerify(facilitatorWallet); + const valid = await verify(facilitatorWallet, firstPaymentPayload, paymentRequirements, { + deferred: { + voucherStore, + }, + }); + expect(valid.isValid).toBe(true); + + // Aggregate multiple times + let currentPayment = firstPaymentPayload; + for (let i = 1; i <= 10; i++) { + const requirements = { + ...paymentRequirements, + maxAmountRequired: "50000", + description: `payment round ${i}`, + extra: { + type: "aggregation", + signature: currentPayment.payload.signature, + voucher: currentPayment.payload.voucher, + }, + } as DeferredPaymentRequirements; + + currentPayment = (await createPayment(buyer, 1, requirements)) as DeferredPaymentPayload; + expect(currentPayment.payload.voucher.nonce).toBe(i); + expect(currentPayment.payload.voucher.valueAggregate).toBe((100000 + i * 50000).toString()); + } + + // Final voucher should have correct accumulated value + expect(currentPayment.payload.voucher.valueAggregate).toBe("600000"); // 100k + 10*50k + expect(currentPayment.payload.voucher.nonce).toBe(10); + }); + }); +}); + +/** + * Mock blockchain interactions for settle facilitator calls + * + * @param wallet - The wallet to mock blockchain interactions for + */ +function mockBlockchainInteractionsSettle(wallet: SignerWallet) { + vi.mocked(wallet.readContract) + .mockResolvedValueOnce([BigInt(1_000_000)]) + .mockResolvedValueOnce({ + balance: BigInt(10_000_000), + }) + .mockResolvedValueOnce([BigInt(1_000_000)]) + .mockResolvedValueOnce({ + balance: BigInt(10_000_000), + }); + vi.mocked(wallet.writeContract).mockResolvedValue("0x1234567890abcdef"); + vi.mocked(wallet.waitForTransactionReceipt).mockResolvedValue({ + status: "success", + logs: [ + { + data: "0x000000000000000000000000036cbd53842c5426634e7929541ec2318f3dcf7e00000000000000000000000000000000000000000000000000000000000003f900000000000000000000000000000000000000000000000000000000000003f90000000000000000000000000000000000000000000000000000000000000000", + topics: [ + "0x70696cf682404a5a47c0a00d3253721b5c093ff0a4c8a13374f53712fc481d77", + "0x198e73e1cecf59db4fbf8ca10000000000000000000000000000000000000000", + "0x00000000000000000000000080cdf1957ebb7a2df22dd8913753a4423ff4272e", + "0x000000000000000000000000c93d37ad45c907ee1b27a02b2e1bd823ba9d379c", + ], + } as unknown as Log, + ], + } as TransactionReceipt); +} + +/** + * Mock blockchain interactions for verify facilitator calls + * + * @param wallet - The wallet to mock blockchain interactions for + */ +function mockBlockchainInteractionsVerify(wallet: SignerWallet) { + vi.mocked(wallet.readContract) + .mockResolvedValueOnce([BigInt(1_000_000)]) + .mockResolvedValueOnce({ + balance: BigInt(10_000_000), + }); +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts b/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts new file mode 100644 index 0000000000..55bdc57628 --- /dev/null +++ b/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts @@ -0,0 +1,214 @@ +import { + DeferredEvmPayloadSignedVoucher, + DeferredEvmPayloadVoucher, + DeferredVoucherCollection, +} from "../../../types"; +import { VoucherStore, VoucherStoreActionResult } from "./store"; + +/** + * In-memory implementation of the VoucherStore interface for testing and development + * + * This class provides a non-persistent storage solution for X402 deferred EVM vouchers. + * It maintains vouchers and their collection records in memory arrays, making it suitable + * for unit tests, integration tests, and local development environments. + * + * WARNING: do not use in production + * This voucher store implementation does not persist data between application restarts + * and might not be feature complete. + */ +export class InMemoryVoucherStore extends VoucherStore { + public vouchers: Array = []; + public collections: Array = []; + + /** + * Get a voucher by its id and nonce + * + * @param id - The id of the voucher + * @param nonce - The nonce of the voucher + * @returns The voucher or null if not found + */ + async getVoucher(id: string, nonce?: number): Promise { + if (nonce !== undefined) { + return this.vouchers.find(voucher => voucher.id === id && voucher.nonce === nonce) ?? null; + } + + return ( + this.vouchers + .filter(voucher => voucher.id === id) + .sort((a, b) => b.nonce - a.nonce) + .at(0) ?? null + ); + } + + /** + * Get a series of vouchers by their id + * + * @param id - The id of the voucher series + * @param pagination - The pagination options + * @param pagination.limit - The maximum number of vouchers to return + * @param pagination.offset - The offset of the first voucher to return + * @returns The vouchers in the series + */ + async getVoucherSeries( + id: string, + pagination: { + limit?: number | undefined; + offset?: number | undefined; + }, + ): Promise> { + const { limit = 100, offset = 0 } = pagination; + return this.vouchers + .filter(voucher => voucher.id === id) + .sort((a, b) => b.nonce - a.nonce) + .slice(offset, offset + limit); + } + + /** + * Get all vouchers matching the query + * + * @param query - The query options + * @param query.buyer - The buyer's address + * @param query.seller - The seller's address + * @param query.latest - Whether to return only the latest voucher per series + * @param pagination - The pagination options + * @param pagination.limit - The maximum number of vouchers to return + * @param pagination.offset - The offset of the first voucher to return + * @returns The vouchers matching the query + */ + async getVouchers( + query: { + buyer?: string | undefined; + seller?: string | undefined; + latest?: boolean | undefined; + }, + pagination: { + limit?: number | undefined; + offset?: number | undefined; + }, + ): Promise> { + const { limit = 100, offset = 0 } = pagination; + const { buyer, latest, seller } = query; + + // Filter vouchers by buyer and/or seller + let filteredVouchers = this.vouchers.filter(voucher => { + if (buyer && voucher.buyer !== buyer) return false; + if (seller && voucher.seller !== seller) return false; + return true; + }); + + // If latest=true, return only the latest voucher per series ID + if (latest) { + const voucherMap = new Map(); + + filteredVouchers.forEach(voucher => { + const existing = voucherMap.get(voucher.id); + if (!existing || voucher.nonce > existing.nonce) { + voucherMap.set(voucher.id, voucher); + } + }); + + filteredVouchers = Array.from(voucherMap.values()); + } + + // Sort by nonce descending, then by timestamp descending + return filteredVouchers + .sort((a, b) => { + if (b.nonce !== a.nonce) return b.nonce - a.nonce; + return b.timestamp - a.timestamp; + }) + .slice(offset, offset + limit); + } + + /** + * Get the "latest available" voucher for a given buyer and seller + * + * @param buyer - The buyer's address + * @param seller - The seller's address + * @returns The available voucher or null if none available + */ + async getAvailableVoucher( + buyer: string, + seller: string, + ): Promise { + // Get all vouchers for this buyer/seller pair + const vouchers = this.vouchers.filter( + voucher => voucher.buyer === buyer && voucher.seller === seller, + ); + + if (vouchers.length === 0) return null; + + // Group by series ID and find the highest nonce per series + const voucherMap = new Map(); + vouchers.forEach(voucher => { + const existing = voucherMap.get(voucher.id); + if (!existing || voucher.nonce > existing.nonce) { + voucherMap.set(voucher.id, voucher); + } + }); + + // Sort by timestamp descending to get the most recent + const latestVouchers = Array.from(voucherMap.values()).sort( + (a, b) => b.timestamp - a.timestamp, + ); + + return latestVouchers.at(0) ?? null; + } + + /** + * Store a voucher + * + * @param voucher - The voucher to store + * @returns The result of the operation + */ + async storeVoucher(voucher: DeferredEvmPayloadSignedVoucher): Promise { + if (this.vouchers.some(v => v.id === voucher.id && v.nonce === voucher.nonce)) { + return { success: false, error: "Voucher already exists" }; + } + + this.vouchers.push(voucher); + return { success: true }; + } + + /** + * Settle a voucher + * + * @param voucher - The voucher to settle + * @param txHash - The transaction hash of the settlement + * @param amount - The amount of the settlement + * @returns The result of the operation + */ + async settleVoucher( + voucher: DeferredEvmPayloadVoucher, + txHash: string, + amount: bigint, + ): Promise { + this.collections.push({ + voucherId: voucher.id, + voucherNonce: voucher.nonce, + transactionHash: txHash, + collectedAmount: amount.toString(), + asset: voucher.asset, + chainId: voucher.chainId, + collectedAt: Date.now(), + }); + return { success: true }; + } + + /** + * Get the voucher collections for a given voucher id and nonce + * + * @param id - The id of the voucher + * @param nonce - The nonce of the voucher + * @returns The voucher collections + */ + async getVoucherCollections( + id: string, + nonce: number, + ): Promise> { + return this.collections.filter( + collection => collection.voucherId === id && collection.voucherNonce === nonce, + ); + } +} + +export const voucherStore = new InMemoryVoucherStore(); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/store.ts b/typescript/packages/x402/src/schemes/deferred/evm/store.ts index a308f10ecb..94630ab3dc 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/store.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/store.ts @@ -143,7 +143,6 @@ export abstract class VoucherStore { * Store a new voucher in the system * * @param voucher - The signed voucher to store - * @param signature - The cryptographic signature * @returns Result indicating success/failure * * @example @@ -158,7 +157,6 @@ export abstract class VoucherStore { */ abstract storeVoucher( voucher: DeferredEvmPayloadSignedVoucher, - signature: string, ): Promise; /** diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts index a827c0a35a..3a6315e1c6 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts @@ -11,7 +11,7 @@ import { verifyVoucherSignature, verifyOnchainState, verifyVoucherContinuity, - verifyPreviousVoucherAvailability, + verifyVoucherAvailability, verifyVoucherDuplicate, } from "./verify"; import { ConnectedClient, createSigner } from "../../../types/shared/evm/wallet"; @@ -750,7 +750,7 @@ describe("verifyVoucherSignature", async () => { }); }); -describe("verifyPreviousVoucherAvailability", () => { +describe("verifyVoucherAvailability", () => { const mockVoucher = { id: voucherId, buyer: buyerAddress, @@ -785,9 +785,11 @@ describe("verifyPreviousVoucherAvailability", () => { it("should return valid response when previous voucher is found and matches", async () => { vi.mocked(mockVoucherStore.getVoucher).mockResolvedValue(mockSignedVoucher); - const result = await verifyPreviousVoucherAvailability( + const result = await verifyVoucherAvailability( mockVoucher, voucherSignature, + mockVoucher.id, + mockVoucher.nonce, mockVoucherStore, ); @@ -801,15 +803,17 @@ describe("verifyPreviousVoucherAvailability", () => { it("should return error when previous voucher is not found in store", async () => { vi.mocked(mockVoucherStore.getVoucher).mockResolvedValue(null); - const result = await verifyPreviousVoucherAvailability( + const result = await verifyVoucherAvailability( mockVoucher, voucherSignature, + mockVoucher.id, + mockVoucher.nonce, mockVoucherStore, ); expect(result).toEqual({ isValid: false, - invalidReason: "invalid_deferred_evm_payload_previous_voucher_not_found", + invalidReason: "invalid_deferred_evm_payload_voucher_not_found", payer: buyerAddress, }); }); @@ -822,15 +826,17 @@ describe("verifyPreviousVoucherAvailability", () => { vi.mocked(mockVoucherStore.getVoucher).mockResolvedValue(mismatchedVoucher); - const result = await verifyPreviousVoucherAvailability( + const result = await verifyVoucherAvailability( mockVoucher, voucherSignature, + mockVoucher.id, + mockVoucher.nonce, mockVoucherStore, ); expect(result).toEqual({ isValid: false, - invalidReason: "invalid_deferred_evm_payload_voucher_not_duplicate", + invalidReason: "invalid_deferred_evm_payload_voucher_found_not_duplicate", payer: buyerAddress, }); }); @@ -839,7 +845,13 @@ describe("verifyPreviousVoucherAvailability", () => { vi.mocked(mockVoucherStore.getVoucher).mockRejectedValue(new Error("Store error")); await expect( - verifyPreviousVoucherAvailability(mockVoucher, voucherSignature, mockVoucherStore), + verifyVoucherAvailability( + mockVoucher, + voucherSignature, + mockVoucher.id, + mockVoucher.nonce, + mockVoucherStore, + ), ).rejects.toThrow("Store error"); }); }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index 1378b78ec9..f617ffd304 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -275,23 +275,30 @@ export async function verifyVoucherSignature( } /** - * Verifies the previous voucher is available in the voucher store + * Verifies a voucher is available in the voucher store + * + * This function will retrieve voucher (id,nonce) and verify it + * against the voucher provided. * * @param voucher - The voucher to verify * @param signature - The signature of the voucher + * @param id - The id of the voucher + * @param nonce - The nonce of the voucher * @param voucherStore - The voucher store to use for verification * @returns Verification result */ -export async function verifyPreviousVoucherAvailability( +export async function verifyVoucherAvailability( voucher: DeferredEvmPayloadVoucher, signature: string, + id: string, + nonce: number, voucherStore: VoucherStore, ): Promise { - const storeVoucher = await voucherStore.getVoucher(voucher.id, voucher.nonce); + const storeVoucher = await voucherStore.getVoucher(id, nonce); if (!storeVoucher) { return { isValid: false, - invalidReason: "invalid_deferred_evm_payload_previous_voucher_not_found", + invalidReason: "invalid_deferred_evm_payload_voucher_not_found", payer: voucher.buyer, }; } @@ -302,7 +309,11 @@ export async function verifyPreviousVoucherAvailability( const duplicateResult = verifyVoucherDuplicate(signedVoucher, storeVoucher); if (!duplicateResult.isValid) { - return duplicateResult; + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_voucher_found_not_duplicate", + payer: voucher.buyer, + }; } return { diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 8be349f3de..4a58cdb93e 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -38,11 +38,11 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_voucher_timestamp_decreasing", "invalid_deferred_evm_payload_voucher_expiry_decreasing", "invalid_deferred_evm_payload_voucher_zero_value_aggregate", - "invalid_deferred_evm_payload_previous_voucher_not_found", "invalid_deferred_evm_payload_voucher_not_duplicate", "invalid_deferred_evm_payload_voucher_could_not_settle_store", "invalid_deferred_evm_payload_voucher_error_settling_store", - "invalid_deferred_evm_payload_voucher_voucher_not_found", + "invalid_deferred_evm_payload_voucher_not_found", + "invalid_deferred_evm_payload_voucher_found_not_duplicate", ] as const; // x402DeferredEvmPayloadVoucher From e7fe85dc2a0c74b2453c4a9af55718e7e0817815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 27 Aug 2025 15:14:29 -0300 Subject: [PATCH 060/116] chore: update x402-express library to latest design MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-express/src/index.ts | 95 ++----------------- 1 file changed, 9 insertions(+), 86 deletions(-) diff --git a/typescript/packages/x402-express/src/index.ts b/typescript/packages/x402-express/src/index.ts index e39f5a97ee..8749d79540 100644 --- a/typescript/packages/x402-express/src/index.ts +++ b/typescript/packages/x402-express/src/index.ts @@ -26,8 +26,7 @@ import { DEFERRRED_SCHEME, DeferredEvmPayloadSchema, EXACT_SCHEME, - DeferredEvmPayloadVoucher, - PaymentRequirementsExtra, + DeferredEvmPayloadSignedVoucher, } from "x402/types"; import { useFacilitator } from "x402/verify"; @@ -367,7 +366,7 @@ export function paymentMiddleware( * * @param payTo - The address to receive payments * @param routes - Configuration for protected routes and their payment requirements - * @param retrieveVoucher - A function to get the latest voucher for a given buyer and seller. Needs to be implemented by the server. + * @param getAvailableVoucher - A function to get the latest voucher for a given buyer and seller. Needs to be implemented by the server. * @param escrow - The escrow address * @param storeVoucher - A function to store the voucher. Needs to be implemented by the server. * @param facilitator - Optional configuration for the payment facilitator service @@ -425,12 +424,12 @@ export function paymentMiddleware( export function deferredPaymentMiddleware( payTo: Address, routes: RoutesConfig, - retrieveVoucher: ( + getAvailableVoucher: ( buyer: string, seller: string, - ) => Promise<(DeferredEvmPayloadVoucher & { signature: string }) | null>, + ) => Promise, escrow: Address, - storeVoucher: (voucher: DeferredEvmPayloadVoucher, signature: string) => Promise, + storeVoucher: (voucher: DeferredEvmPayloadSignedVoucher) => Promise, facilitator?: FacilitatorConfig, ) { const { verify } = useFacilitator(facilitator); @@ -477,12 +476,12 @@ export function deferredPaymentMiddleware( maxTimeoutSeconds: maxTimeoutSeconds ?? 60, asset: getAddress(asset.address), outputSchema: outputSchema ?? undefined, - extra: await getPaymentRequirementsExtra( + extra: await deferred.evm.getPaymentRequirementsExtra( payment, - paymentBuyer, + paymentBuyer as `0x${string}` | undefined, payTo, escrow, - retrieveVoucher, + getAvailableVoucher, ), }, ]; @@ -553,7 +552,7 @@ export function deferredPaymentMiddleware( try { const { voucher, signature } = DeferredEvmPayloadSchema.parse(decodedPayment.payload); - await storeVoucher(voucher, signature); + await storeVoucher({ ...voucher, signature }); } catch (error) { console.error(error); res.status(402).json({ @@ -569,82 +568,6 @@ export function deferredPaymentMiddleware( }; } -/** - * Get the extra data for the payment requirements - * - * @param paymentHeader - The x-payment header - * @param paymentBuyerHeader - The x-payment-buyer header - * @param seller - The seller address - * @param escrow - The escrow address - * @param retrieveVoucher - A function to get the latest voucher for a given buyer and seller. - * @returns The extra data for the payment requirements - */ -async function getPaymentRequirementsExtra( - paymentHeader: string | undefined, - paymentBuyerHeader: string | undefined, - seller: Address, - escrow: Address, - retrieveVoucher: ( - buyer: string, - seller: string, - ) => Promise<(DeferredEvmPayloadVoucher & { signature: string }) | null>, -): Promise { - const newVoucher = { - type: "new" as const, - voucher: { - id: deferred.evm.generateVoucherId(), - escrow, - }, - }; - - // No header, new voucher - if (!paymentHeader) { - if (paymentBuyerHeader) { - const latestVoucher = await retrieveVoucher(paymentBuyerHeader, seller); - - // No voucher history, new voucher - if (!latestVoucher) { - return newVoucher; - } - - // If we made it here, means we need to aggregate the last voucher - return { - type: "aggregation" as const, - signature: latestVoucher.signature, - voucher: { - ...latestVoucher, - }, - }; - } - return newVoucher; - } - - // Wrong payload, new voucher - const paymentRequirements = DeferredEvmPayloadSchema.safeParse( - deferred.evm.decodePayment(paymentHeader).payload, - ); - if (!paymentRequirements.success) { - return newVoucher; - } - - // Get the latest voucher for the buyer - const latestVoucher = await retrieveVoucher(paymentRequirements.data.voucher.buyer, seller); - - // No voucher history, new voucher - if (!latestVoucher) { - return newVoucher; - } - - // If we made it here, means we need to aggregate the last voucher - return { - type: "aggregation" as const, - signature: latestVoucher.signature, - voucher: { - ...latestVoucher, - }, - }; -} - export type { Money, Network, From bb9e01804b2ae55e4793ac1e7d22c490a397d524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 27 Aug 2025 15:55:27 -0300 Subject: [PATCH 061/116] feat: add verifyAndStore fn to facilitator client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/verify/useDeferred.test.ts | 281 ++++++++++++++++-- .../packages/x402/src/verify/useDeferred.ts | 83 ++++-- .../x402/src/verify/useFacilitator.ts | 8 +- 3 files changed, 316 insertions(+), 56 deletions(-) diff --git a/typescript/packages/x402/src/verify/useDeferred.test.ts b/typescript/packages/x402/src/verify/useDeferred.test.ts index f7f5d7dbbc..c7400dc577 100644 --- a/typescript/packages/x402/src/verify/useDeferred.test.ts +++ b/typescript/packages/x402/src/verify/useDeferred.test.ts @@ -6,6 +6,8 @@ import { DeferredErrorResponse, DeferredVoucherResponse, DeferredVouchersResponse, + PaymentRequirements, + PaymentPayload, } from "../types"; // Mock fetch globally @@ -48,7 +50,7 @@ describe("useDeferredFacilitator", () => { describe("useDeferredFacilitator initialization and configuration", () => { it("should instantiate a valid facilitator", () => { - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); expect(facilitator).toHaveProperty("getVoucher"); expect(facilitator).toHaveProperty("getVoucherSeries"); expect(facilitator).toHaveProperty("getVouchers"); @@ -64,7 +66,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockSignedVoucher), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await facilitator.getVoucher(voucherId, 0); expect(mockFetch).toHaveBeenCalledWith( @@ -94,7 +96,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockSignedVoucher), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); const result = await facilitator.getVoucher(voucherId, 0); expect(result).toEqual(mockSignedVoucher); @@ -114,7 +116,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.getVoucher(voucherId, 0)).rejects.toThrow("Voucher not found"); }); @@ -129,7 +131,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.getVoucher(voucherId, 0)).rejects.toThrow("Internal server error"); }); @@ -141,7 +143,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve({}), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.getVoucher(voucherId, 0)).rejects.toThrow( "Failed to fetch voucher history: Internal Server Error", @@ -161,7 +163,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); const result = await facilitator.getVoucherSeries(voucherId, {}); expect(result).toEqual(mockResponse); @@ -181,7 +183,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); const result = await facilitator.getVoucherSeries(voucherId, { limit: 10, offset: 5 }); expect(result).toEqual(mockResponse); @@ -201,7 +203,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.getVoucherSeries(voucherId, {})).rejects.toThrow("Series not found"); }); @@ -216,7 +218,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.getVoucherSeries(voucherId, {})).rejects.toThrow( "Internal server error", @@ -230,7 +232,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve({}), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.getVoucherSeries(voucherId, {})).rejects.toThrow( "Failed to fetch voucher history: Internal Server Error", @@ -250,7 +252,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); const result = await facilitator.getVouchers( { buyer: buyerAddress, seller: sellerAddress }, {}, @@ -273,7 +275,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); const result = await facilitator.getVouchers( { buyer: buyerAddress, seller: sellerAddress, latest: true }, { limit: 50, offset: 10 }, @@ -296,7 +298,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect( facilitator.getVouchers({ buyer: buyerAddress, seller: sellerAddress }, {}), @@ -313,7 +315,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect( facilitator.getVouchers({ buyer: buyerAddress, seller: sellerAddress }, {}), @@ -327,7 +329,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve({}), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect( facilitator.getVouchers({ buyer: buyerAddress, seller: sellerAddress }, {}), @@ -343,7 +345,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); const result = await facilitator.getAvailableVoucher(buyerAddress, sellerAddress); expect(result).toEqual(mockResponse); @@ -358,7 +360,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve({ error: "voucher_not_found" }), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); const result = await facilitator.getAvailableVoucher(buyerAddress, sellerAddress); expect(result).toEqual({ error: "voucher_not_found" }); @@ -375,7 +377,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.getAvailableVoucher(buyerAddress, sellerAddress)).rejects.toThrow( "Server error", @@ -392,7 +394,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.getAvailableVoucher(buyerAddress, sellerAddress)).rejects.toThrow( "Voucher validation failed", @@ -406,7 +408,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve({}), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.getAvailableVoucher(buyerAddress, sellerAddress)).rejects.toThrow( "Failed to fetch available voucher: Forbidden", @@ -422,7 +424,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); const result = await facilitator.storeVoucher(mockSignedVoucher); expect(result).toEqual(mockResponse); @@ -446,7 +448,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.storeVoucher(mockSignedVoucher)).rejects.toThrow("Voucher invalid"); }); @@ -461,7 +463,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.storeVoucher(mockSignedVoucher)).rejects.toThrow( "Internal server error", @@ -475,7 +477,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve({}), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.storeVoucher(mockSignedVoucher)).rejects.toThrow( "Failed to store voucher: Internal Server Error", @@ -492,7 +494,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); const result = await facilitator.verifyVoucher(voucherId, 0); expect(result).toEqual(mockResponse); @@ -515,7 +517,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.verifyVoucher(voucherId, 0)).rejects.toThrow( "Failed to verify voucher: Bad Request", @@ -529,7 +531,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve({}), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.verifyVoucher(voucherId, 0)).rejects.toThrow( "Failed to verify voucher: Not Found", @@ -550,7 +552,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); const result = await facilitator.settleVoucher(voucherId, 0); expect(result).toEqual(mockResponse); @@ -573,7 +575,7 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve(mockErrorResponse), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.settleVoucher(voucherId, 0)).rejects.toThrow( "Failed to settle voucher: Internal Server Error", @@ -587,11 +589,228 @@ describe("useDeferredFacilitator", () => { json: () => Promise.resolve({}), }); - const facilitator = useDeferredFacilitator(); + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect(facilitator.settleVoucher(voucherId, 0)).rejects.toThrow( "Failed to settle voucher: Service Unavailable", ); }); }); + + describe("verifyAndStoreVoucher", () => { + const mockPaymentPayload = { + x402Version: 1, + scheme: "deferred", + network: "base-sepolia", + payload: { + signature: voucherSignature, + voucher: { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + }, + }, + } as PaymentPayload; + + const mockPaymentRequirements = { + scheme: "deferred", + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test payment", + mimeType: "application/json", + payTo: sellerAddress, + maxTimeoutSeconds: 300, + asset: assetAddress, + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + }, + } as PaymentRequirements; + + it("should verify and store voucher successfully", async () => { + const mockResponse: DeferredVoucherResponse = mockSignedVoucher; + + mockFetch.mockResolvedValueOnce({ + status: 201, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + const result = await facilitator.verifyAndStoreVoucher( + mockPaymentPayload, + mockPaymentRequirements, + ); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/verify-and-store`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + x402Version: mockPaymentPayload.x402Version, + paymentPayload: mockPaymentPayload, + paymentRequirements: mockPaymentRequirements, + }), + }, + ); + }); + + it("should throw error for non-201 status", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Verification failed", + }; + + mockFetch.mockResolvedValueOnce({ + status: 400, + statusText: "Bad Request", + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + + await expect( + facilitator.verifyAndStoreVoucher(mockPaymentPayload, mockPaymentRequirements), + ).rejects.toThrow("Verification failed"); + }); + + it("should throw error when response contains error field", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Invalid voucher signature", + }; + + mockFetch.mockResolvedValueOnce({ + status: 201, + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + + await expect( + facilitator.verifyAndStoreVoucher(mockPaymentPayload, mockPaymentRequirements), + ).rejects.toThrow("Invalid voucher signature"); + }); + + it("should throw error when response contains invalidReason field", async () => { + const mockVerifyResponse = { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_signature", + payer: buyerAddress, + }; + + mockFetch.mockResolvedValueOnce({ + status: 201, + json: () => Promise.resolve(mockVerifyResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + + await expect( + facilitator.verifyAndStoreVoucher(mockPaymentPayload, mockPaymentRequirements), + ).rejects.toThrow("invalid_deferred_evm_payload_signature"); + }); + + it("should use fallback error message when no specific error provided", async () => { + mockFetch.mockResolvedValueOnce({ + status: 500, + statusText: "Internal Server Error", + json: () => Promise.resolve({}), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + + await expect( + facilitator.verifyAndStoreVoucher(mockPaymentPayload, mockPaymentRequirements), + ).rejects.toThrow("Failed to verify and store voucher: Internal Server Error"); + }); + + it("should handle complex payment requirements with aggregation", async () => { + const aggregationRequirements = { + ...mockPaymentRequirements, + extra: { + type: "aggregation", + signature: voucherSignature, + voucher: { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "500000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + }, + }, + } as PaymentRequirements; + + const mockResponse: DeferredVoucherResponse = { + ...mockSignedVoucher, + valueAggregate: "1500000", + nonce: 1, + }; + + mockFetch.mockResolvedValueOnce({ + status: 201, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + const result = await facilitator.verifyAndStoreVoucher( + mockPaymentPayload, + aggregationRequirements, + ); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/verify-and-store`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + x402Version: mockPaymentPayload.x402Version, + paymentPayload: mockPaymentPayload, + paymentRequirements: aggregationRequirements, + }), + }, + ); + }); + + it("should use custom facilitator URL", async () => { + const mockResponse: DeferredVoucherResponse = mockSignedVoucher; + + mockFetch.mockResolvedValueOnce({ + status: 201, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: customFacilitatorUrl }); + const result = await facilitator.verifyAndStoreVoucher( + mockPaymentPayload, + mockPaymentRequirements, + ); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${customFacilitatorUrl}/deferred/verify-and-store`, + expect.any(Object), + ); + }); + }); }); diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index ad71875e2a..88371774cf 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -1,21 +1,23 @@ +import { toJsonSafe } from "../shared/json"; import { DeferredErrorResponse, DeferredEvmPayloadSignedVoucher, DeferredVoucherResponse, DeferredVouchersResponse, FacilitatorConfig, + PaymentPayload, + PaymentRequirements, SettleResponse, VerifyResponse, } from "../types"; -import { DEFAULT_FACILITATOR_URL } from "./useFacilitator"; /** - * Creates a facilitator client for interacting with the X402 payment facilitator service + * Creates a facilitator client for interacting with the X402 payment deferred facilitator service * - * @param facilitator - The facilitator config to use. If not provided, the default facilitator will be used. - * @returns An object containing verify and settle functions for interacting with the facilitator + * @param facilitator - The facilitator config to use. + * @returns An object containing functions for interacting with a deferred facilitator */ -export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { +export function useDeferredFacilitator(facilitator: FacilitatorConfig) { /** * Fetches a voucher by its id and nonce. * @@ -24,9 +26,7 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { * @returns The voucher */ async function getVoucher(id: string, nonce: number): Promise { - const url = facilitator?.url || DEFAULT_FACILITATOR_URL; - - const response = await fetch(`${url}/deferred/vouchers/${id}/${nonce}`); + const response = await fetch(`${facilitator.url}/deferred/vouchers/${id}/${nonce}`); const responseJson = (await response.json()) as DeferredVoucherResponse; if (response.status !== 200 || "error" in responseJson) { @@ -54,7 +54,6 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { offset?: number; }, ): Promise { - const url = facilitator?.url || DEFAULT_FACILITATOR_URL; const { limit, offset } = pagination; const params = new URLSearchParams(); @@ -63,7 +62,7 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { const queryString = params.toString(); const response = await fetch( - `${url}/deferred/vouchers/${id}${queryString ? `?${queryString}` : ""}`, + `${facilitator.url}/deferred/vouchers/${id}${queryString ? `?${queryString}` : ""}`, ); const responseJson = (await response.json()) as DeferredVouchersResponse; @@ -99,7 +98,6 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { offset?: number; }, ): Promise { - const url = facilitator?.url || DEFAULT_FACILITATOR_URL; const { buyer, seller, latest } = query; const { limit, offset } = pagination; @@ -111,7 +109,9 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { if (seller !== undefined) params.append("seller", seller); const queryString = params.toString(); - const response = await fetch(`${url}/deferred/vouchers${queryString ? `?${queryString}` : ""}`); + const response = await fetch( + `${facilitator.url}/deferred/vouchers${queryString ? `?${queryString}` : ""}`, + ); const responseJson = (await response.json()) as DeferredVouchersResponse; if (response.status !== 200 || "error" in responseJson) { @@ -134,9 +134,9 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { buyer: string, seller: string, ): Promise { - const url = facilitator?.url || DEFAULT_FACILITATOR_URL; - - const response = await fetch(`${url}/deferred/vouchers/available/${buyer}/${seller}`); + const response = await fetch( + `${facilitator.url}/deferred/vouchers/available/${buyer}/${seller}`, + ); const responseJson = (await response.json()) as DeferredVoucherResponse; // If the voucher is not found we don't throw, clients should just create a new voucher from scratch @@ -165,9 +165,7 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { async function storeVoucher( voucher: DeferredEvmPayloadSignedVoucher, ): Promise { - const url = facilitator?.url || DEFAULT_FACILITATOR_URL; - - const response = await fetch(`${url}/deferred/vouchers`, { + const response = await fetch(`${facilitator.url}/deferred/vouchers`, { method: "POST", body: JSON.stringify(voucher), headers: { @@ -194,9 +192,7 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { * @returns The verification result */ async function verifyVoucher(id: string, nonce: number): Promise { - const url = facilitator?.url || DEFAULT_FACILITATOR_URL; - - const response = await fetch(`${url}/deferred/vouchers/${id}/${nonce}/verify`, { + const response = await fetch(`${facilitator.url}/deferred/vouchers/${id}/${nonce}/verify`, { method: "POST", }); const responseJson = await response.json(); @@ -217,9 +213,7 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { * @returns The settlement result */ async function settleVoucher(id: string, nonce: number): Promise { - const url = facilitator?.url || DEFAULT_FACILITATOR_URL; - - const response = await fetch(`${url}/deferred/vouchers/${id}/${nonce}/settle`, { + const response = await fetch(`${facilitator.url}/deferred/vouchers/${id}/${nonce}/settle`, { method: "POST", }); const responseJson = await response.json(); @@ -232,6 +226,46 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { return responseJson as SettleResponse; } + /** + * Verifies a voucher and stores it if it is valid + * + * This is the equivalent of calling the following in sequence: + * 1. POST /verify (facilitator verify) + * 2. POST /deferred/vouchers (store voucher) + * + * @param payload - The payment payload + * @param paymentRequirements - The payment requirements + * @returns The voucher response + */ + async function verifyAndStoreVoucher( + payload: PaymentPayload, + paymentRequirements: PaymentRequirements, + ): Promise { + const response = await fetch(`${facilitator.url}/deferred/verify-and-store`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + x402Version: payload.x402Version, + paymentPayload: toJsonSafe(payload), + paymentRequirements: toJsonSafe(paymentRequirements), + }), + }); + + const responseJson = (await response.json()) as VerifyResponse | DeferredVoucherResponse; + + if (response.status !== 201 || "error" in responseJson || "invalidReason" in responseJson) { + const errorMessage = + (responseJson as DeferredErrorResponse).error || + (responseJson as VerifyResponse).invalidReason || + `Failed to verify and store voucher: ${response.statusText}`; + throw new Error(errorMessage); + } + + return responseJson as VerifyResponse | DeferredVoucherResponse; + } + return { getVoucher, getVouchers, @@ -240,5 +274,6 @@ export function useDeferredFacilitator(facilitator?: FacilitatorConfig) { storeVoucher, verifyVoucher, settleVoucher, + verifyAndStoreVoucher, }; } diff --git a/typescript/packages/x402/src/verify/useFacilitator.ts b/typescript/packages/x402/src/verify/useFacilitator.ts index 377b92d133..cfb3257efb 100644 --- a/typescript/packages/x402/src/verify/useFacilitator.ts +++ b/typescript/packages/x402/src/verify/useFacilitator.ts @@ -170,7 +170,13 @@ export function useFacilitator(facilitator?: FacilitatorConfig) { return data as ListDiscoveryResourcesResponse; } - return { verify, settle, supported, list, deferred: useDeferredFacilitator(facilitator) }; + return { + verify, + settle, + supported, + list, + deferred: useDeferredFacilitator(facilitator || { url: DEFAULT_FACILITATOR_URL }), + }; } export const { verify, settle, supported, list, deferred } = useFacilitator(); From 41aeb35b7a8e02bd9538eab44a828c4545381020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 27 Aug 2025 15:59:40 -0300 Subject: [PATCH 062/116] fix: use correct endpoint for verify and store deferred MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/verify/useDeferred.test.ts | 2 +- typescript/packages/x402/src/verify/useDeferred.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/typescript/packages/x402/src/verify/useDeferred.test.ts b/typescript/packages/x402/src/verify/useDeferred.test.ts index c7400dc577..a35c704138 100644 --- a/typescript/packages/x402/src/verify/useDeferred.test.ts +++ b/typescript/packages/x402/src/verify/useDeferred.test.ts @@ -777,7 +777,7 @@ describe("useDeferredFacilitator", () => { expect(result).toEqual(mockResponse); expect(mockFetch).toHaveBeenCalledWith( - `${DEFAULT_FACILITATOR_URL}/deferred/verify-and-store`, + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/verify`, { method: "POST", headers: { diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index 88371774cf..61db05f736 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -241,7 +241,7 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { payload: PaymentPayload, paymentRequirements: PaymentRequirements, ): Promise { - const response = await fetch(`${facilitator.url}/deferred/verify-and-store`, { + const response = await fetch(`${facilitator.url}/deferred/vouchers/verify`, { method: "POST", headers: { "Content-Type": "application/json", From 94c833f710192aad974a1ec9a5eb289e7103641e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 27 Aug 2025 16:37:21 -0300 Subject: [PATCH 063/116] test: fix verify and store test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/verify/useDeferred.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/typescript/packages/x402/src/verify/useDeferred.test.ts b/typescript/packages/x402/src/verify/useDeferred.test.ts index a35c704138..d4d7fec1f7 100644 --- a/typescript/packages/x402/src/verify/useDeferred.test.ts +++ b/typescript/packages/x402/src/verify/useDeferred.test.ts @@ -654,7 +654,7 @@ describe("useDeferredFacilitator", () => { expect(result).toEqual(mockResponse); expect(mockFetch).toHaveBeenCalledWith( - `${DEFAULT_FACILITATOR_URL}/deferred/verify-and-store`, + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/verify`, { method: "POST", headers: { @@ -808,7 +808,7 @@ describe("useDeferredFacilitator", () => { expect(result).toEqual(mockResponse); expect(mockFetch).toHaveBeenCalledWith( - `${customFacilitatorUrl}/deferred/verify-and-store`, + `${customFacilitatorUrl}/deferred/vouchers/verify`, expect.any(Object), ); }); From 2d4d6a96df6f373446e43afe4e2ae0075a345cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 28 Aug 2025 10:32:13 -0300 Subject: [PATCH 064/116] fix: simpliufy voucher store creatgion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/verify/useDeferred.test.ts | 142 ++++-------------- .../packages/x402/src/verify/useDeferred.ts | 71 +++------ 2 files changed, 48 insertions(+), 165 deletions(-) diff --git a/typescript/packages/x402/src/verify/useDeferred.test.ts b/typescript/packages/x402/src/verify/useDeferred.test.ts index d4d7fec1f7..fde570a0a2 100644 --- a/typescript/packages/x402/src/verify/useDeferred.test.ts +++ b/typescript/packages/x402/src/verify/useDeferred.test.ts @@ -416,75 +416,6 @@ describe("useDeferredFacilitator", () => { }); }); - describe("storeVoucher", () => { - it("should store voucher successfully", async () => { - const mockResponse: DeferredVoucherResponse = mockSignedVoucher; - mockFetch.mockResolvedValueOnce({ - status: 201, - json: () => Promise.resolve(mockResponse), - }); - - const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); - const result = await facilitator.storeVoucher(mockSignedVoucher); - - expect(result).toEqual(mockResponse); - expect(mockFetch).toHaveBeenCalledWith(`${DEFAULT_FACILITATOR_URL}/deferred/vouchers`, { - method: "POST", - body: JSON.stringify(mockResponse), - headers: { - "Content-Type": "application/json", - }, - }); - }); - - it("should throw error for non-201 status", async () => { - const mockErrorResponse: DeferredErrorResponse = { - error: "Voucher invalid", - }; - - mockFetch.mockResolvedValueOnce({ - status: 400, - statusText: "Bad Request", - json: () => Promise.resolve(mockErrorResponse), - }); - - const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); - - await expect(facilitator.storeVoucher(mockSignedVoucher)).rejects.toThrow("Voucher invalid"); - }); - - it("should throw error when response contains error field", async () => { - const mockErrorResponse: DeferredErrorResponse = { - error: "Internal server error", - }; - - mockFetch.mockResolvedValueOnce({ - status: 201, - json: () => Promise.resolve(mockErrorResponse), - }); - - const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); - - await expect(facilitator.storeVoucher(mockSignedVoucher)).rejects.toThrow( - "Internal server error", - ); - }); - - it("should use fallback error message", async () => { - mockFetch.mockResolvedValueOnce({ - status: 500, - statusText: "Internal Server Error", - json: () => Promise.resolve({}), - }); - - const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); - - await expect(facilitator.storeVoucher(mockSignedVoucher)).rejects.toThrow( - "Failed to store voucher: Internal Server Error", - ); - }); - }); - describe("verifyVoucher", () => { it("should verify voucher successfully", async () => { const mockResponse = { isValid: true, payer: buyerAddress }; @@ -597,7 +528,7 @@ describe("useDeferredFacilitator", () => { }); }); - describe("verifyAndStoreVoucher", () => { + describe("storeVoucher", () => { const mockPaymentPayload = { x402Version: 1, scheme: "deferred", @@ -647,26 +578,20 @@ describe("useDeferredFacilitator", () => { }); const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); - const result = await facilitator.verifyAndStoreVoucher( - mockPaymentPayload, - mockPaymentRequirements, - ); + const result = await facilitator.storeVoucher(mockPaymentPayload, mockPaymentRequirements); expect(result).toEqual(mockResponse); - expect(mockFetch).toHaveBeenCalledWith( - `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/verify`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - x402Version: mockPaymentPayload.x402Version, - paymentPayload: mockPaymentPayload, - paymentRequirements: mockPaymentRequirements, - }), + expect(mockFetch).toHaveBeenCalledWith(`${DEFAULT_FACILITATOR_URL}/deferred/vouchers`, { + method: "POST", + headers: { + "Content-Type": "application/json", }, - ); + body: JSON.stringify({ + x402Version: mockPaymentPayload.x402Version, + paymentPayload: mockPaymentPayload, + paymentRequirements: mockPaymentRequirements, + }), + }); }); it("should throw error for non-201 status", async () => { @@ -683,7 +608,7 @@ describe("useDeferredFacilitator", () => { const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect( - facilitator.verifyAndStoreVoucher(mockPaymentPayload, mockPaymentRequirements), + facilitator.storeVoucher(mockPaymentPayload, mockPaymentRequirements), ).rejects.toThrow("Verification failed"); }); @@ -700,7 +625,7 @@ describe("useDeferredFacilitator", () => { const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect( - facilitator.verifyAndStoreVoucher(mockPaymentPayload, mockPaymentRequirements), + facilitator.storeVoucher(mockPaymentPayload, mockPaymentRequirements), ).rejects.toThrow("Invalid voucher signature"); }); @@ -719,7 +644,7 @@ describe("useDeferredFacilitator", () => { const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect( - facilitator.verifyAndStoreVoucher(mockPaymentPayload, mockPaymentRequirements), + facilitator.storeVoucher(mockPaymentPayload, mockPaymentRequirements), ).rejects.toThrow("invalid_deferred_evm_payload_signature"); }); @@ -733,7 +658,7 @@ describe("useDeferredFacilitator", () => { const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); await expect( - facilitator.verifyAndStoreVoucher(mockPaymentPayload, mockPaymentRequirements), + facilitator.storeVoucher(mockPaymentPayload, mockPaymentRequirements), ).rejects.toThrow("Failed to verify and store voucher: Internal Server Error"); }); @@ -770,26 +695,20 @@ describe("useDeferredFacilitator", () => { }); const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); - const result = await facilitator.verifyAndStoreVoucher( - mockPaymentPayload, - aggregationRequirements, - ); + const result = await facilitator.storeVoucher(mockPaymentPayload, aggregationRequirements); expect(result).toEqual(mockResponse); - expect(mockFetch).toHaveBeenCalledWith( - `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/verify`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - x402Version: mockPaymentPayload.x402Version, - paymentPayload: mockPaymentPayload, - paymentRequirements: aggregationRequirements, - }), + expect(mockFetch).toHaveBeenCalledWith(`${DEFAULT_FACILITATOR_URL}/deferred/vouchers`, { + method: "POST", + headers: { + "Content-Type": "application/json", }, - ); + body: JSON.stringify({ + x402Version: mockPaymentPayload.x402Version, + paymentPayload: mockPaymentPayload, + paymentRequirements: aggregationRequirements, + }), + }); }); it("should use custom facilitator URL", async () => { @@ -801,14 +720,11 @@ describe("useDeferredFacilitator", () => { }); const facilitator = useDeferredFacilitator({ url: customFacilitatorUrl }); - const result = await facilitator.verifyAndStoreVoucher( - mockPaymentPayload, - mockPaymentRequirements, - ); + const result = await facilitator.storeVoucher(mockPaymentPayload, mockPaymentRequirements); expect(result).toEqual(mockResponse); expect(mockFetch).toHaveBeenCalledWith( - `${customFacilitatorUrl}/deferred/vouchers/verify`, + `${customFacilitatorUrl}/deferred/vouchers`, expect.any(Object), ); }); diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index 61db05f736..69f254a77a 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -1,7 +1,6 @@ import { toJsonSafe } from "../shared/json"; import { DeferredErrorResponse, - DeferredEvmPayloadSignedVoucher, DeferredVoucherResponse, DeferredVouchersResponse, FacilitatorConfig, @@ -157,31 +156,40 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { } /** - * Stores a voucher in the facilitator + * Stores a voucher in the facilitator. Before storing, it verifies the payload and payment + * requirements, equivalent to calling POST /verify * - * @param voucher - The signedvoucher to store - * @returns The result of the store operation + * @param payload - The payment payload + * @param paymentRequirements - The payment requirements + * @returns The voucher response */ async function storeVoucher( - voucher: DeferredEvmPayloadSignedVoucher, - ): Promise { + payload: PaymentPayload, + paymentRequirements: PaymentRequirements, + ): Promise { const response = await fetch(`${facilitator.url}/deferred/vouchers`, { method: "POST", - body: JSON.stringify(voucher), headers: { "Content-Type": "application/json", }, + body: JSON.stringify({ + x402Version: payload.x402Version, + paymentPayload: toJsonSafe(payload), + paymentRequirements: toJsonSafe(paymentRequirements), + }), }); - const responseJson = (await response.json()) as DeferredVoucherResponse; - if (response.status !== 201 || "error" in responseJson) { + const responseJson = (await response.json()) as VerifyResponse | DeferredVoucherResponse; + + if (response.status !== 201 || "error" in responseJson || "invalidReason" in responseJson) { const errorMessage = (responseJson as DeferredErrorResponse).error || - `Failed to store voucher: ${response.statusText}`; + (responseJson as VerifyResponse).invalidReason || + `Failed to verify and store voucher: ${response.statusText}`; throw new Error(errorMessage); } - return responseJson as DeferredVoucherResponse; + return responseJson as VerifyResponse | DeferredVoucherResponse; } /** @@ -226,46 +234,6 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { return responseJson as SettleResponse; } - /** - * Verifies a voucher and stores it if it is valid - * - * This is the equivalent of calling the following in sequence: - * 1. POST /verify (facilitator verify) - * 2. POST /deferred/vouchers (store voucher) - * - * @param payload - The payment payload - * @param paymentRequirements - The payment requirements - * @returns The voucher response - */ - async function verifyAndStoreVoucher( - payload: PaymentPayload, - paymentRequirements: PaymentRequirements, - ): Promise { - const response = await fetch(`${facilitator.url}/deferred/vouchers/verify`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - x402Version: payload.x402Version, - paymentPayload: toJsonSafe(payload), - paymentRequirements: toJsonSafe(paymentRequirements), - }), - }); - - const responseJson = (await response.json()) as VerifyResponse | DeferredVoucherResponse; - - if (response.status !== 201 || "error" in responseJson || "invalidReason" in responseJson) { - const errorMessage = - (responseJson as DeferredErrorResponse).error || - (responseJson as VerifyResponse).invalidReason || - `Failed to verify and store voucher: ${response.statusText}`; - throw new Error(errorMessage); - } - - return responseJson as VerifyResponse | DeferredVoucherResponse; - } - return { getVoucher, getVouchers, @@ -274,6 +242,5 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { storeVoucher, verifyVoucher, settleVoucher, - verifyAndStoreVoucher, }; } From 4e2d0d1d8d8172cf7819034dcfb369a7da79b0fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 28 Aug 2025 14:40:10 -0300 Subject: [PATCH 065/116] feat: add get collections to facilitator client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/store.mock.ts | 31 ++- .../x402/src/schemes/deferred/evm/store.ts | 16 +- .../x402/src/types/verify/schemes/deferred.ts | 16 ++ .../x402/src/verify/useDeferred.test.ts | 186 ++++++++++++++++++ .../packages/x402/src/verify/useDeferred.ts | 49 ++++- 5 files changed, 285 insertions(+), 13 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts b/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts index 55bdc57628..e3b3db4f65 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts @@ -197,17 +197,34 @@ export class InMemoryVoucherStore extends VoucherStore { /** * Get the voucher collections for a given voucher id and nonce * - * @param id - The id of the voucher - * @param nonce - The nonce of the voucher + * @param query - The query options + * @param query.id - The id of the voucher + * @param query.nonce - The nonce of the voucher + * @param pagination - The pagination options + * @param pagination.limit - The maximum number of collections to return + * @param pagination.offset - The offset of the first collection to return * @returns The voucher collections */ async getVoucherCollections( - id: string, - nonce: number, + query: { + id?: string | undefined; + nonce?: number | undefined; + }, + pagination: { + limit?: number | undefined; + offset?: number | undefined; + }, ): Promise> { - return this.collections.filter( - collection => collection.voucherId === id && collection.voucherNonce === nonce, - ); + const { limit = 100, offset = 0 } = pagination; + const { id, nonce } = query; + + return this.collections + .filter(collection => { + if (id && collection.voucherId !== id) return false; + if (nonce && collection.voucherNonce !== nonce) return false; + return true; + }) + .slice(offset, offset + limit); } } diff --git a/typescript/packages/x402/src/schemes/deferred/evm/store.ts b/typescript/packages/x402/src/schemes/deferred/evm/store.ts index 94630ab3dc..a1076901b2 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/store.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/store.ts @@ -182,18 +182,24 @@ export abstract class VoucherStore { /** * Get the collections for a voucher * - * @param id - The voucher id - * @param nonce - The voucher nonce + * @param query - The voucher id and nonce + * @param pagination - Pagination options * @returns The collections for the voucher * * @example * ```typescript * // Get the collections for a voucher - * const collections = await store.getVoucherCollections("0x123...", 5); + * const collections = await store.getVoucherCollections({ id: "0x123...", nonce: 5 }, { limit: 10, offset: 0 }); * ``` */ abstract getVoucherCollections( - id: string, - nonce: number, + query: { + id?: string; + nonce?: number; + }, + pagination: { + limit?: number; + offset?: number; + }, ): Promise>; } diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 4a58cdb93e..131bbccce3 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -177,3 +177,19 @@ export const DeferredVoucherCollectionResponseSchema = z.object({ export type DeferredVoucherCollectionResponse = z.infer< typeof DeferredVoucherCollectionResponseSchema >; + +// x402DeferredVoucherCollectionsResponse +export const DeferredVoucherCollectionsResponseSchema = z.union([ + z.object({ + data: z.array(DeferredVoucherCollectionSchema), + count: z.number(), + pagination: z.object({ + limit: z.number(), + offset: z.number(), + }), + }), + DeferredErrorResponseSchema, +]); +export type DeferredVoucherCollectionsResponse = z.infer< + typeof DeferredVoucherCollectionsResponseSchema +>; diff --git a/typescript/packages/x402/src/verify/useDeferred.test.ts b/typescript/packages/x402/src/verify/useDeferred.test.ts index fde570a0a2..485f51e732 100644 --- a/typescript/packages/x402/src/verify/useDeferred.test.ts +++ b/typescript/packages/x402/src/verify/useDeferred.test.ts @@ -58,6 +58,7 @@ describe("useDeferredFacilitator", () => { expect(facilitator).toHaveProperty("storeVoucher"); expect(facilitator).toHaveProperty("verifyVoucher"); expect(facilitator).toHaveProperty("settleVoucher"); + expect(facilitator).toHaveProperty("getVoucherCollections"); }); it("should use default facilitator URL when no config provided", async () => { @@ -729,4 +730,189 @@ describe("useDeferredFacilitator", () => { ); }); }); + + describe("getVoucherCollections", () => { + it("should fetch voucher collections without query or pagination", async () => { + const mockResponse = { + data: [ + { + id: voucherId, + nonce: 0, + transaction: "0xabcdef1234567890", + timestamp: 1715769600, + }, + ], + count: 1, + pagination: { limit: 10, offset: 0 }, + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + const result = await facilitator.getVoucherCollections({}, {}); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/collections`, + ); + }); + + it("should fetch voucher collections with id and nonce query", async () => { + const mockResponse = { + data: [ + { + id: voucherId, + nonce: 2, + transaction: "0xabcdef1234567890", + timestamp: 1715769600, + }, + ], + count: 1, + pagination: { limit: 10, offset: 0 }, + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + const result = await facilitator.getVoucherCollections({ id: voucherId, nonce: 2 }, {}); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/collections?id=${voucherId}&nonce=2`, + ); + }); + + it("should fetch voucher collections with pagination", async () => { + const mockResponse = { + data: [ + { + id: voucherId, + nonce: 0, + transaction: "0xabcdef1234567890", + timestamp: 1715769600, + }, + ], + count: 1, + pagination: { limit: 20, offset: 10 }, + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + const result = await facilitator.getVoucherCollections({}, { limit: 20, offset: 10 }); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/collections?limit=20&offset=10`, + ); + }); + + it("should fetch voucher collections with all parameters", async () => { + const mockResponse = { + data: [ + { + id: voucherId, + nonce: 3, + transaction: "0xabcdef1234567890", + timestamp: 1715769600, + }, + ], + count: 1, + pagination: { limit: 50, offset: 25 }, + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + const result = await facilitator.getVoucherCollections( + { id: voucherId, nonce: 3 }, + { limit: 50, offset: 25 }, + ); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/vouchers/collections?limit=50&offset=25&id=${voucherId}&nonce=3`, + ); + }); + + it("should throw error for non-200 status", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Collections not found", + }; + + mockFetch.mockResolvedValueOnce({ + status: 404, + statusText: "Not Found", + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + + await expect(facilitator.getVoucherCollections({}, {})).rejects.toThrow( + "Collections not found", + ); + }); + + it("should throw error when response contains error field", async () => { + const mockErrorResponse: DeferredErrorResponse = { + error: "Database error", + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + + await expect(facilitator.getVoucherCollections({}, {})).rejects.toThrow("Database error"); + }); + + it("should use fallback error message when no error field", async () => { + mockFetch.mockResolvedValueOnce({ + status: 500, + statusText: "Internal Server Error", + json: () => Promise.resolve({}), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + + await expect(facilitator.getVoucherCollections({}, {})).rejects.toThrow( + "Failed to fetch voucher collections: Internal Server Error", + ); + }); + + it("should use custom facilitator URL", async () => { + const mockResponse = { + data: [], + count: 0, + pagination: { limit: 10, offset: 0 }, + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: customFacilitatorUrl }); + const result = await facilitator.getVoucherCollections({}, {}); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${customFacilitatorUrl}/deferred/vouchers/collections`, + ); + }); + }); }); diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index 69f254a77a..503f1de005 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -1,6 +1,7 @@ import { toJsonSafe } from "../shared/json"; import { DeferredErrorResponse, + DeferredVoucherCollectionsResponse, DeferredVoucherResponse, DeferredVouchersResponse, FacilitatorConfig, @@ -75,7 +76,7 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { } /** - * Fetches the latest voucher for a given buyer and seller + * Fetches vouchers for a given buyer and seller * * @param query - The query parameters * @param query.buyer - The buyer address @@ -234,6 +235,51 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { return responseJson as SettleResponse; } + /** + * Fetches the latest voucher for a given buyer and seller + * + * @param query - The query parameters + * @param query.id - The id of the voucher + * @param query.nonce - The nonce of the voucher + * @param pagination - The pagination parameters + * @param pagination.limit - The maximum number of vouchers to return + * @param pagination.offset - The offset to start from + * @returns The vouchers + */ + async function getVoucherCollections( + query: { + id?: string; + nonce?: number; + }, + pagination: { + limit?: number; + offset?: number; + }, + ): Promise { + const { id, nonce } = query; + const { limit, offset } = pagination; + + const params = new URLSearchParams(); + if (limit !== undefined) params.append("limit", limit.toString()); + if (offset !== undefined) params.append("offset", offset.toString()); + if (id !== undefined) params.append("id", id); + if (nonce !== undefined) params.append("nonce", nonce.toString()); + const queryString = params.toString(); + + const response = await fetch( + `${facilitator.url}/deferred/vouchers/collections${queryString ? `?${queryString}` : ""}`, + ); + const responseJson = (await response.json()) as DeferredVoucherCollectionsResponse; + + if (response.status !== 200 || "error" in responseJson) { + const errorMessage = + (responseJson as DeferredErrorResponse).error || + `Failed to fetch voucher collections: ${response.statusText}`; + throw new Error(errorMessage); + } + return responseJson; + } + return { getVoucher, getVouchers, @@ -242,5 +288,6 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { storeVoucher, verifyVoucher, settleVoucher, + getVoucherCollections, }; } From d302d6b2d5f6af664594887d1d65bc3d0e00b6b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 28 Aug 2025 14:41:35 -0300 Subject: [PATCH 066/116] fix: bug in mock store voucher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts b/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts index e3b3db4f65..033d6e2dd2 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts @@ -221,7 +221,7 @@ export class InMemoryVoucherStore extends VoucherStore { return this.collections .filter(collection => { if (id && collection.voucherId !== id) return false; - if (nonce && collection.voucherNonce !== nonce) return false; + if (nonce !== undefined && collection.voucherNonce !== nonce) return false; return true; }) .slice(offset, offset + limit); From 4e175952c6203ad82c24cf950c72d51619429e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 25 Sep 2025 14:45:08 -0300 Subject: [PATCH 067/116] fix: issues after resyncing with main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/client/createPaymentHeader.ts | 8 ++++++- .../client/selectPaymentRequirements.test.ts | 10 +++++---- .../x402/src/client/signPaymentHeader.ts | 10 +++++++-- .../x402/src/facilitator/facilitator.ts | 14 +++++++++++-- .../schemes/deferred/evm/integration.test.ts | 21 +++++++++++++------ .../deferred/evm/utils/paymentUtils.test.ts | 2 +- .../x402/src/schemes/exact/evm/client.test.ts | 10 +++++++-- .../exact/evm/utils/paymentUtils.test.ts | 2 +- .../schemes/exact/evm/utils/paymentUtils.ts | 13 ++++++------ .../x402/src/schemes/exact/svm/client.test.ts | 2 +- .../x402/src/schemes/exact/svm/client.ts | 16 +++++++++----- .../exact/svm/facilitator/verify.test.ts | 17 +++++++-------- .../schemes/exact/svm/facilitator/verify.ts | 4 ++-- .../x402/src/shared/middleware.test.ts | 5 ++--- .../x402/src/shared/svm/transaction.ts | 2 +- .../x402/src/types/verify/schemes/exact.ts | 1 + .../x402/src/types/verify/x402Specs.ts | 8 +++---- .../x402/src/verify/useFacilitator.test.ts | 2 ++ .../x402/src/verify/useFacilitator.ts | 1 + 19 files changed, 97 insertions(+), 51 deletions(-) diff --git a/typescript/packages/x402/src/client/createPaymentHeader.ts b/typescript/packages/x402/src/client/createPaymentHeader.ts index de963d4894..db4f056fac 100644 --- a/typescript/packages/x402/src/client/createPaymentHeader.ts +++ b/typescript/packages/x402/src/client/createPaymentHeader.ts @@ -56,7 +56,13 @@ export async function createPaymentHeader( paymentRequirements.scheme === DEFERRRED_SCHEME && SupportedEVMNetworks.includes(paymentRequirements.network) ) { - return await createPaymentHeaderDeferredEVM(client, x402Version, paymentRequirements); + const evmClient = isMultiNetworkSigner(client) ? client.evm : client; + + if (!isEvmSignerWallet(evmClient)) { + throw new Error("Invalid evm wallet client provided"); + } + + return await createPaymentHeaderDeferredEVM(evmClient, x402Version, paymentRequirements); } throw new Error("Unsupported scheme"); diff --git a/typescript/packages/x402/src/client/selectPaymentRequirements.test.ts b/typescript/packages/x402/src/client/selectPaymentRequirements.test.ts index a031c2dee9..4bc9d67324 100644 --- a/typescript/packages/x402/src/client/selectPaymentRequirements.test.ts +++ b/typescript/packages/x402/src/client/selectPaymentRequirements.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from "vitest"; import { selectPaymentRequirements } from "./selectPaymentRequirements"; -import { PaymentRequirements, Network } from "../types"; +import { PaymentRequirements, Network, EXACT_SCHEME, type X402_SCHEMES } from "../types"; import { getUsdcChainConfigForChain } from "../shared/evm"; import { getNetworkId } from "../shared/network"; @@ -10,15 +10,17 @@ import { getNetworkId } from "../shared/network"; * @param network - The network to create the payment requirement for. * @param asset - The asset to create the payment requirement for. * @param overrides - The overrides to apply to the payment requirement. + * @param scheme - The scheme to create the payment requirement for. * @returns The created payment requirement. */ function makeRequirement( network: Network, asset: string, - overrides: Partial = {}, + overrides: Partial> = {}, + scheme: X402_SCHEMES = EXACT_SCHEME, ): PaymentRequirements { return { - scheme: "exact", + scheme, network, maxAmountRequired: "1000", resource: "https://example.com/resource", @@ -28,7 +30,7 @@ function makeRequirement( maxTimeoutSeconds: 300, asset, ...overrides, - }; + } as PaymentRequirements; } describe("selectPaymentRequirements", () => { diff --git a/typescript/packages/x402/src/client/signPaymentHeader.ts b/typescript/packages/x402/src/client/signPaymentHeader.ts index 50828d5f07..546e237c57 100644 --- a/typescript/packages/x402/src/client/signPaymentHeader.ts +++ b/typescript/packages/x402/src/client/signPaymentHeader.ts @@ -32,7 +32,7 @@ export async function signPaymentHeader( throw new Error("Invalid evm wallet client provided"); } unsignedPaymentHeader = UnsignedExactPaymentPayloadSchema.parse(unsignedPaymentHeader); - const signedPaymentHeader = await signPaymentHeaderExactEVM(client, paymentRequirements, unsignedPaymentHeader); + const signedPaymentHeader = await signPaymentHeaderExactEVM(evmClient, paymentRequirements, unsignedPaymentHeader); return encodePaymentExactEVM(signedPaymentHeader); } @@ -40,8 +40,14 @@ export async function signPaymentHeader( paymentRequirements.scheme === DEFERRRED_SCHEME && SupportedEVMNetworks.includes(paymentRequirements.network) ) { + const evmClient = isMultiNetworkSigner(client) ? client.evm : client; + + if (!isEvmSignerWallet(evmClient)) { + throw new Error("Invalid evm wallet client provided"); + } + unsignedPaymentHeader = UnsignedDeferredPaymentPayloadSchema.parse(unsignedPaymentHeader); - const signedPaymentHeader = await signPaymentHeaderDeferredEVM(client, unsignedPaymentHeader); + const signedPaymentHeader = await signPaymentHeaderDeferredEVM(evmClient, unsignedPaymentHeader); return encodePaymentDeferredEVM(signedPaymentHeader); } diff --git a/typescript/packages/x402/src/facilitator/facilitator.ts b/typescript/packages/x402/src/facilitator/facilitator.ts index 04a73dd9e4..63e8ade7b7 100644 --- a/typescript/packages/x402/src/facilitator/facilitator.ts +++ b/typescript/packages/x402/src/facilitator/facilitator.ts @@ -69,7 +69,12 @@ export async function verify< payer: payload.payload.voucher.buyer, }; } - const valid = await verifyDeferred(client, payload, paymentRequirements, schemeContext); + const valid = await verifyDeferred( + client as EvmConnectedClient, + payload, + paymentRequirements, + schemeContext, + ); return valid; } else { return { @@ -135,7 +140,12 @@ export async function settle( payer: payload.payload.voucher.buyer, }; } - return settleDeferred(client, payload, paymentRequirements, schemeContext); + return settleDeferred( + client as EvmSignerWallet, + payload, + paymentRequirements, + schemeContext, + ); } else { return { success: false, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts index dbce70cb3a..80fee59bd4 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts @@ -128,8 +128,11 @@ describe("Deferred Payment Integration Tests", () => { expect(settleResponse.success).toBe(true); const voucherCollections = await voucherStore.getVoucherCollections( - decodedPaymentPayload.payload.voucher.id, - decodedPaymentPayload.payload.voucher.nonce, + { + id: decodedPaymentPayload.payload.voucher.id, + nonce: decodedPaymentPayload.payload.voucher.nonce, + }, + {}, ); expect(voucherCollections.length).toBe(1); expect(voucherCollections[0]).toEqual({ @@ -222,8 +225,11 @@ describe("Deferred Payment Integration Tests", () => { expect(settleResponse.success).toBe(true); const voucherCollections = await voucherStore.getVoucherCollections( - decodedPaymentPayload.payload.voucher.id, - decodedPaymentPayload.payload.voucher.nonce, + { + id: decodedPaymentPayload.payload.voucher.id, + nonce: decodedPaymentPayload.payload.voucher.nonce, + }, + {}, ); expect(voucherCollections.length).toBe(1); expect(voucherCollections[0]).toEqual({ @@ -332,8 +338,11 @@ describe("Deferred Payment Integration Tests", () => { expect(settleResponse.success).toBe(true); const voucherCollections = await voucherStore.getVoucherCollections( - decodedPaymentPayload.payload.voucher.id, - decodedPaymentPayload.payload.voucher.nonce, + { + id: decodedPaymentPayload.payload.voucher.id, + nonce: decodedPaymentPayload.payload.voucher.nonce, + }, + {}, ); expect(voucherCollections.length).toBe(1); expect(voucherCollections[0]).toEqual({ diff --git a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts index 14be048f71..dc4980ba7a 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts @@ -220,7 +220,7 @@ describe("paymentUtils", () => { }; const encoded = encodePayment(differentSigPayload); - const decoded = decodePayment(encoded); + const decoded = decodePayment(encoded) as DeferredPaymentPayload; expect(decoded.payload.signature).toBe("0x" + "0".repeat(130)); expect(decoded).toEqual(differentSigPayload); diff --git a/typescript/packages/x402/src/schemes/exact/evm/client.test.ts b/typescript/packages/x402/src/schemes/exact/evm/client.test.ts index 02527309fd..bf8cf145ff 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/client.test.ts @@ -1,6 +1,10 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createSignerSepolia, SignerWallet } from "../../../types/shared/evm"; -import { PaymentRequirements, UnsignedPaymentPayload } from "../../../types/verify"; +import { + ExactEvmPayload, + PaymentRequirements, + UnsignedPaymentPayload, +} from "../../../types/verify"; import { createPaymentHeader, preparePaymentHeader, signPaymentHeader } from "./client"; import { signAuthorization } from "./sign"; import { encodePayment } from "./utils/paymentUtils"; @@ -166,7 +170,9 @@ describe("signPaymentHeader", () => { expect(result.x402Version).toBe(mockUnsignedHeader.x402Version); expect(result.scheme).toBe(mockUnsignedHeader.scheme); expect(result.network).toBe(mockUnsignedHeader.network); - expect(result.payload.authorization).toEqual(mockUnsignedHeader.payload.authorization); + expect((result.payload as ExactEvmPayload).authorization).toEqual( + mockUnsignedHeader.payload.authorization, + ); }); it("should throw an error if signing fails", async () => { diff --git a/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.test.ts b/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.test.ts index 5ad1d07b9f..c0e0b2ea18 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.test.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.test.ts @@ -52,7 +52,7 @@ describe("paymentUtils", () => { it("throws on invalid network in encodePayment", () => { const invalidPayment = { ...validEvmPayment, network: "invalid-network" }; - expect(() => encodePayment(invalidPayment)).toThrow("Invalid network"); + expect(() => encodePayment(invalidPayment as PaymentPayload)).toThrow("Invalid network"); }); it("throws on invalid network in decodePayment", () => { diff --git a/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts b/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts index 4042536968..fa7a044f30 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts @@ -15,13 +15,14 @@ import { * @returns A base64 encoded string representation of the payment payload */ export function encodePayment(payment: PaymentPayload): string { - let safe: PaymentPayload; + let safe: ExactPaymentPayload; + const exactPayment = ExactPaymentPayloadSchema.parse(payment); // evm - if (SupportedEVMNetworks.includes(payment.network)) { - const evmPayload = payment.payload as ExactEvmPayload; + if (SupportedEVMNetworks.includes(exactPayment.network)) { + const evmPayload = exactPayment.payload as ExactEvmPayload; safe = { - ...payment, + ...exactPayment, payload: { ...evmPayload, authorization: Object.fromEntries( @@ -36,8 +37,8 @@ export function encodePayment(payment: PaymentPayload): string { } // svm - if (SupportedSVMNetworks.includes(payment.network)) { - safe = { ...payment, payload: payment.payload as ExactSvmPayload }; + if (SupportedSVMNetworks.includes(exactPayment.network)) { + safe = { ...exactPayment, payload: exactPayment.payload as ExactSvmPayload }; return safeBase64Encode(JSON.stringify(safe)); } diff --git a/typescript/packages/x402/src/schemes/exact/svm/client.test.ts b/typescript/packages/x402/src/schemes/exact/svm/client.test.ts index f5e1a1a31f..f5ec5fe0dc 100644 --- a/typescript/packages/x402/src/schemes/exact/svm/client.test.ts +++ b/typescript/packages/x402/src/schemes/exact/svm/client.test.ts @@ -236,7 +236,7 @@ describe("SVM Client", () => { // Act & Assert await expect( - createAndSignPayment(clientSigner, 1, paymentReqsWithoutFeePayer), + createAndSignPayment(clientSigner, 1, paymentReqsWithoutFeePayer as PaymentRequirements), ).rejects.toThrow( "feePayer is required in paymentRequirements.extra in order to set the facilitator as the fee payer for the create associated token account instruction", ); diff --git a/typescript/packages/x402/src/schemes/exact/svm/client.ts b/typescript/packages/x402/src/schemes/exact/svm/client.ts index bb9301f11c..d0a97f67d8 100644 --- a/typescript/packages/x402/src/schemes/exact/svm/client.ts +++ b/typescript/packages/x402/src/schemes/exact/svm/client.ts @@ -14,7 +14,11 @@ import { TransactionSigner, Instruction, } from "@solana/kit"; -import { PaymentPayload, PaymentRequirements } from "../../../types/verify"; +import { + ExactPaymentRequirementsSchema, + PaymentPayload, + PaymentRequirements, +} from "../../../types/verify"; import { fetchMint, findAssociatedTokenPda, @@ -92,7 +96,8 @@ async function createTransferTransactionMessage( const transferInstructions = await createAtaAndTransferInstructions(client, paymentRequirements); // create tx to simulate - const feePayer = paymentRequirements.extra?.feePayer as Address; + const { extra } = ExactPaymentRequirementsSchema.parse(paymentRequirements); + const feePayer = extra?.feePayer as Address; const txToSimulate = pipe( createTransactionMessage({ version: 0 }), tx => setTransactionMessageComputeUnitPrice(1, tx), // 1 microlamport priority fee @@ -186,14 +191,15 @@ async function createAtaInstructionOrUndefined( paymentRequirements: PaymentRequirements, tokenProgramAddress: Address, ): Promise { - const { asset, payTo, extra, network } = paymentRequirements; + const { asset, payTo, extra, network } = + ExactPaymentRequirementsSchema.parse(paymentRequirements); const feePayer = extra?.feePayer as Address; // feePayer is required if (!feePayer) { throw new Error( "feePayer is required in paymentRequirements.extra in order to set the " + - "facilitator as the fee payer for the create associated token account instruction", + "facilitator as the fee payer for the create associated token account instruction", ); } @@ -211,7 +217,7 @@ async function createAtaInstructionOrUndefined( // if the ATA does not exist, return an instruction to create it if (!maybeAccount.exists) { return getCreateAssociatedTokenInstruction({ - payer: paymentRequirements.extra?.feePayer as TransactionSigner, + payer: extra?.feePayer as unknown as TransactionSigner, ata: destinationATAAddress, owner: payTo as Address, mint: asset as Address, diff --git a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.test.ts b/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.test.ts index c05d0773bb..5b96141d32 100644 --- a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.test.ts +++ b/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.test.ts @@ -17,8 +17,7 @@ import { fetchEncodedAccounts, } from "@solana/kit"; import { PaymentPayload, PaymentRequirements, ExactSvmPayload } from "../../../../types/verify"; -import { Network } from "../../../../types"; -import { SCHEME } from "../../"; +import { EXACT_SCHEME, Network } from "../../../../types"; import * as SvmShared from "../../../../shared/svm"; import { TOKEN_PROGRAM_ADDRESS, @@ -98,7 +97,7 @@ const devnetUSDCAddress = "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"; describe("verify", () => { describe("verifySchemesAndNetworks", () => { const validPayload: PaymentPayload = { - scheme: SCHEME, + scheme: EXACT_SCHEME, network: "solana-devnet", x402Version: 1, payload: { @@ -107,7 +106,7 @@ describe("verify", () => { }; const validRequirements: PaymentRequirements = { - scheme: SCHEME, + scheme: EXACT_SCHEME, network: "solana-devnet", payTo: "someAddress", maxAmountRequired: "1000", @@ -273,7 +272,7 @@ describe("verify", () => { }, }; mockPaymentRequirements = { - scheme: SCHEME, + scheme: EXACT_SCHEME, network: "solana-devnet", payTo: "payToAddress", maxAmountRequired: "1000", @@ -369,13 +368,13 @@ describe("verify", () => { mockSigner = {} as any; mockPayload = { - scheme: SCHEME, + scheme: EXACT_SCHEME, network: "solana-devnet", x402Version: 1, payload: { transaction: "..." } as ExactSvmPayload, }; mockRequirements = { - scheme: SCHEME, + scheme: EXACT_SCHEME, network: "solana-devnet", payTo: "payToAddress", maxAmountRequired: "1000", @@ -446,7 +445,7 @@ describe("verify", () => { }); it("should return isValid: false if schemes or networks are invalid", async () => { - const invalidPayload = { ...mockPayload, scheme: "invalid" as "exact" }; + const invalidPayload = { ...mockPayload, scheme: "invalid" } as unknown as PaymentPayload; const result = await verify(mockSigner, invalidPayload, mockRequirements); expect(result.isValid).toBe(false); expect(result.invalidReason).toBe("unsupported_scheme"); @@ -504,7 +503,7 @@ describe("verify", () => { vi.clearAllMocks(); mockPaymentRequirements = { - scheme: SCHEME, + scheme: EXACT_SCHEME, network: "solana-devnet", payTo: "payToAddress", maxAmountRequired: "1000", diff --git a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.ts b/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.ts index 60306d6661..2bde996ec3 100644 --- a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.ts +++ b/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.ts @@ -4,6 +4,7 @@ import { PaymentRequirements, ExactSvmPayload, ErrorReasons, + EXACT_SCHEME, } from "../../../../types/verify"; import { SupportedSVMNetworks } from "../../../../types/shared"; import { @@ -48,7 +49,6 @@ import { getRpcClient, signAndSimulateTransaction, } from "../../../../shared/svm"; -import { SCHEME } from "../../"; /** * Verify the payment payload against the payment requirements. @@ -115,7 +115,7 @@ export function verifySchemesAndNetworks( payload: PaymentPayload, paymentRequirements: PaymentRequirements, ): void { - if (payload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) { + if (payload.scheme !== EXACT_SCHEME || paymentRequirements.scheme !== EXACT_SCHEME) { throw new Error("unsupported_scheme"); } diff --git a/typescript/packages/x402/src/shared/middleware.test.ts b/typescript/packages/x402/src/shared/middleware.test.ts index b60d1c32ca..cc6afd5404 100644 --- a/typescript/packages/x402/src/shared/middleware.test.ts +++ b/typescript/packages/x402/src/shared/middleware.test.ts @@ -4,9 +4,8 @@ import { findMatchingRoute, getDefaultAsset, processPriceToAtomicAmount, -} from "x402/shared"; -import { RoutesConfig } from "./middleware"; -import { Network } from "./network"; +} from "../shared"; +import { Network, RoutesConfig } from "../types"; describe("computeRoutePatterns", () => { it("should handle simple string price routes", () => { diff --git a/typescript/packages/x402/src/shared/svm/transaction.ts b/typescript/packages/x402/src/shared/svm/transaction.ts index e08b1b0fb9..000a350757 100644 --- a/typescript/packages/x402/src/shared/svm/transaction.ts +++ b/typescript/packages/x402/src/shared/svm/transaction.ts @@ -1,4 +1,4 @@ -import { ExactSvmPayload } from "../../types/verify/x402Specs"; +import { ExactSvmPayload } from "../../types/verify"; import { getBase64EncodedWireTransaction, getBase64Encoder, diff --git a/typescript/packages/x402/src/types/verify/schemes/exact.ts b/typescript/packages/x402/src/types/verify/schemes/exact.ts index fdb18d7de2..b0194b8e25 100644 --- a/typescript/packages/x402/src/types/verify/schemes/exact.ts +++ b/typescript/packages/x402/src/types/verify/schemes/exact.ts @@ -92,6 +92,7 @@ export const ExactPaymentRequirementsSchema = BasePaymentRequirementsSchema.exte .object({ name: z.string().optional(), version: z.string().optional(), + feePayer: z.string().regex(EvmAddressRegex).optional(), }) .optional(), }); diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index 82a5050172..c01b89e168 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -20,7 +20,8 @@ import { x402Versions } from "./versions"; import { EvmOrSvmAddress } from ".."; // Enums -export const schemes = [EXACT_SCHEME, DEFERRRED_SCHEME] as const; +export const X402_SCHEMES = [EXACT_SCHEME, DEFERRRED_SCHEME] as const; +export type X402_SCHEMES = (typeof X402_SCHEMES)[number]; export const ErrorReasons = [ "insufficient_funds", "invalid_network", @@ -65,7 +66,6 @@ export const UnsignedPaymentPayloadSchema = z.discriminatedUnion("scheme", [ ]); export type UnsignedPaymentPayload = z.infer; -<<<<<<< HEAD // x402 Resource Server Response export const x402ResponseSchema = z.object({ x402Version: z.number().refine(val => x402Versions.includes(val as 1)), @@ -138,14 +138,12 @@ export const VerifyRequestSchema = z.object({ paymentRequirements: PaymentRequirementsSchema, }); export type VerifyRequest = z.infer; -======= // x402Request export const X402RequestSchema = z.object({ paymentRequirements: PaymentRequirementsSchema, paymentPayload: PaymentPayloadSchema, }); export type X402Request = z.infer; ->>>>>>> d96a8bb (chore: lint code) // x402VerifyResponse export const VerifyResponseSchema = z.object({ @@ -188,7 +186,7 @@ export type ListDiscoveryResourcesResponse = z.infer x402Versions.includes(val as 1)), - scheme: z.enum(schemes), + scheme: z.enum(X402_SCHEMES), network: NetworkSchema, extra: z.record(z.any()).optional(), }); diff --git a/typescript/packages/x402/src/verify/useFacilitator.test.ts b/typescript/packages/x402/src/verify/useFacilitator.test.ts index 5cb527da2e..28ae6f4c50 100644 --- a/typescript/packages/x402/src/verify/useFacilitator.test.ts +++ b/typescript/packages/x402/src/verify/useFacilitator.test.ts @@ -170,6 +170,7 @@ describe("useFacilitator", () => { const mockHeaders = { verify: { Authorization: "Bearer test-token" }, settle: { Authorization: "Bearer test-token" }, + supported: { Authorization: "Bearer test-token" }, }; const { verify } = useFacilitator({ url: "https://x402.org/facilitator", @@ -292,6 +293,7 @@ describe("useFacilitator", () => { const mockHeaders = { verify: { Authorization: "Bearer test-token" }, settle: { Authorization: "Bearer test-token" }, + supported: { Authorization: "Bearer test-token" }, }; const { settle } = useFacilitator({ url: "https://x402.org/facilitator", diff --git a/typescript/packages/x402/src/verify/useFacilitator.ts b/typescript/packages/x402/src/verify/useFacilitator.ts index cfb3257efb..6fe66f1edb 100644 --- a/typescript/packages/x402/src/verify/useFacilitator.ts +++ b/typescript/packages/x402/src/verify/useFacilitator.ts @@ -20,6 +20,7 @@ export type CreateHeaders = () => Promise<{ settle: Record; supported: Record; list?: Record; + deferred?: Record; }>; /** From 61779cfbd4d402dae46b95bf666c48ae528d8c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 25 Sep 2025 16:07:05 -0300 Subject: [PATCH 068/116] fix: make sure x402 test suite passes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../schemes/exact/evm/utils/paymentUtils.ts | 19 +++++++++++++------ .../exact/svm/facilitator/verify.test.ts | 4 +++- .../schemes/exact/svm/facilitator/verify.ts | 2 +- .../x402/src/types/verify/constants.ts | 1 + .../packages/x402/src/types/verify/index.ts | 1 + .../x402/src/types/verify/schemes/exact.ts | 3 ++- .../x402/src/types/verify/schemes/index.ts | 6 ------ .../x402/src/types/verify/x402Specs.ts | 2 +- 8 files changed, 22 insertions(+), 16 deletions(-) diff --git a/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts b/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts index fa7a044f30..12772d31b5 100644 --- a/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts +++ b/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts @@ -1,5 +1,10 @@ import { safeBase64Encode, safeBase64Decode } from "../../../../shared"; -import { SupportedEVMNetworks, SupportedSVMNetworks } from "../../../../types"; +import { + ExactEvmPayloadSchema, + ExactSvmPayloadSchema, + SupportedEVMNetworks, + SupportedSVMNetworks, +} from "../../../../types"; import { PaymentPayload, ExactEvmPayload, @@ -16,11 +21,11 @@ import { */ export function encodePayment(payment: PaymentPayload): string { let safe: ExactPaymentPayload; - const exactPayment = ExactPaymentPayloadSchema.parse(payment); // evm - if (SupportedEVMNetworks.includes(exactPayment.network)) { - const evmPayload = exactPayment.payload as ExactEvmPayload; + if (SupportedEVMNetworks.includes(payment.network)) { + const exactPayment = ExactPaymentPayloadSchema.parse(payment); + const evmPayload = ExactEvmPayloadSchema.parse(exactPayment.payload); safe = { ...exactPayment, payload: { @@ -37,8 +42,10 @@ export function encodePayment(payment: PaymentPayload): string { } // svm - if (SupportedSVMNetworks.includes(exactPayment.network)) { - safe = { ...exactPayment, payload: exactPayment.payload as ExactSvmPayload }; + if (SupportedSVMNetworks.includes(payment.network)) { + const exactPayment = ExactPaymentPayloadSchema.parse(payment); + const svmPayload = ExactSvmPayloadSchema.parse(exactPayment.payload); + safe = { ...exactPayment, payload: svmPayload }; return safeBase64Encode(JSON.stringify(safe)); } diff --git a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.test.ts b/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.test.ts index 5b96141d32..334720d683 100644 --- a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.test.ts +++ b/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.test.ts @@ -17,7 +17,7 @@ import { fetchEncodedAccounts, } from "@solana/kit"; import { PaymentPayload, PaymentRequirements, ExactSvmPayload } from "../../../../types/verify"; -import { EXACT_SCHEME, Network } from "../../../../types"; +import { Network } from "../../../../types"; import * as SvmShared from "../../../../shared/svm"; import { TOKEN_PROGRAM_ADDRESS, @@ -38,6 +38,7 @@ import { parseSetComputeUnitLimitInstruction, parseSetComputeUnitPriceInstruction, } from "@solana-program/compute-budget"; +import { EXACT_SCHEME } from "../../../../types/verify/schemes"; vi.mock("@solana/kit", async () => { const actual = await vi.importActual("@solana/kit"); @@ -482,6 +483,7 @@ describe("verify", () => { }); it("should return isValid: false if simulation fails", async () => { + console.log("SCHEME", EXACT_SCHEME); vi.mocked(SvmShared.signAndSimulateTransaction).mockResolvedValue({ value: { err: "simulation_error" }, } as any); diff --git a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.ts b/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.ts index 2bde996ec3..67654a3302 100644 --- a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.ts +++ b/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.ts @@ -4,7 +4,6 @@ import { PaymentRequirements, ExactSvmPayload, ErrorReasons, - EXACT_SCHEME, } from "../../../../types/verify"; import { SupportedSVMNetworks } from "../../../../types/shared"; import { @@ -49,6 +48,7 @@ import { getRpcClient, signAndSimulateTransaction, } from "../../../../shared/svm"; +import { EXACT_SCHEME } from "../../../../types/verify/schemes"; /** * Verify the payment payload against the payment requirements. diff --git a/typescript/packages/x402/src/types/verify/constants.ts b/typescript/packages/x402/src/types/verify/constants.ts index 45776da315..a1a912fc80 100644 --- a/typescript/packages/x402/src/types/verify/constants.ts +++ b/typescript/packages/x402/src/types/verify/constants.ts @@ -1,6 +1,7 @@ // Constants export const EvmMaxAtomicUnits = 18; export const EvmAddressRegex = /^0x[0-9a-fA-F]{40}$/; +export const SvmAddressRegex = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/; export const MixedAddressRegex = /^0x[a-fA-F0-9]{40}|[A-Za-z0-9][A-Za-z0-9-]{0,34}[A-Za-z0-9]$/; export const HexEncoded64ByteRegex = /^0x[0-9a-fA-F]{64}$/; export const EvmSignatureRegex = /^0x[0-9a-fA-F]+$/; // Flexible hex signature validation diff --git a/typescript/packages/x402/src/types/verify/index.ts b/typescript/packages/x402/src/types/verify/index.ts index 47a540f8e6..0c8e0d52fd 100644 --- a/typescript/packages/x402/src/types/verify/index.ts +++ b/typescript/packages/x402/src/types/verify/index.ts @@ -3,4 +3,5 @@ export * from "./schemes"; export * from "./facilitator"; export * from "./constants"; export * from "./refiners"; +export * from "./schemes"; export * from "./versions"; diff --git a/typescript/packages/x402/src/types/verify/schemes/exact.ts b/typescript/packages/x402/src/types/verify/schemes/exact.ts index b0194b8e25..308e651c66 100644 --- a/typescript/packages/x402/src/types/verify/schemes/exact.ts +++ b/typescript/packages/x402/src/types/verify/schemes/exact.ts @@ -4,6 +4,7 @@ import { EvmSignatureRegex, HexEncoded64ByteRegex, EvmMaxAtomicUnits, + SvmAddressRegex, } from "../constants"; import { hasMaxLength, isInteger } from "../refiners"; import { Base64EncodedRegex } from "../../../shared"; @@ -92,7 +93,7 @@ export const ExactPaymentRequirementsSchema = BasePaymentRequirementsSchema.exte .object({ name: z.string().optional(), version: z.string().optional(), - feePayer: z.string().regex(EvmAddressRegex).optional(), + feePayer: z.string().regex(SvmAddressRegex).optional(), }) .optional(), }); diff --git a/typescript/packages/x402/src/types/verify/schemes/index.ts b/typescript/packages/x402/src/types/verify/schemes/index.ts index 52f109b7e5..5de123cfb7 100644 --- a/typescript/packages/x402/src/types/verify/schemes/index.ts +++ b/typescript/packages/x402/src/types/verify/schemes/index.ts @@ -1,9 +1,3 @@ -import { DEFERRRED_SCHEME } from "./deferred"; -import { EXACT_SCHEME } from "./exact"; - export * from "./base"; export * from "./deferred"; export * from "./exact"; - -export const SCHEMES = [EXACT_SCHEME, DEFERRRED_SCHEME] as const; -export type SCHEMES = (typeof SCHEMES)[number]; diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/x402/src/types/verify/x402Specs.ts index c01b89e168..a54230598e 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/x402/src/types/verify/x402Specs.ts @@ -17,7 +17,7 @@ import { UnsignedDeferredPaymentPayloadSchema, } from "./schemes/deferred"; import { x402Versions } from "./versions"; -import { EvmOrSvmAddress } from ".."; +import { EvmOrSvmAddress } from "./schemes/base"; // Enums export const X402_SCHEMES = [EXACT_SCHEME, DEFERRRED_SCHEME] as const; From 892aa6ea1f5e310eb6c84a43e3ed434b7d1f4009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 25 Sep 2025 17:50:58 -0300 Subject: [PATCH 069/116] tests: fix x402-axios tests after resync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../fullstack/farcaster-miniapp/package.json | 4 +- examples/typescript/pnpm-lock.yaml | 7162 +++++++---------- .../packages/x402-axios/src/index.test.ts | 282 +- typescript/packages/x402-axios/src/index.ts | 19 +- .../src/client/selectPaymentRequirements.ts | 6 +- .../x402/src/schemes/exact/svm/client.ts | 2 +- 6 files changed, 2879 insertions(+), 4596 deletions(-) diff --git a/examples/typescript/fullstack/farcaster-miniapp/package.json b/examples/typescript/fullstack/farcaster-miniapp/package.json index e1302526f2..a56914b5f2 100644 --- a/examples/typescript/fullstack/farcaster-miniapp/package.json +++ b/examples/typescript/fullstack/farcaster-miniapp/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@coinbase/onchainkit": "latest", - "@coinbase/x402": "latest", + "@coinbase/x402": "workspace:*", "@farcaster/frame-sdk": "^0.0.60", "@tanstack/react-query": "^5", "@upstash/redis": "^1.34.4", @@ -42,4 +42,4 @@ "tailwindcss": "^3.4.1", "typescript": "^5" } -} +} \ No newline at end of file diff --git a/examples/typescript/pnpm-lock.yaml b/examples/typescript/pnpm-lock.yaml index f6ec500465..aab67f046d 100644 --- a/examples/typescript/pnpm-lock.yaml +++ b/examples/typescript/pnpm-lock.yaml @@ -10,10 +10,10 @@ importers: devDependencies: tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) turbo: specifier: ^2.5.0 - version: 2.5.8 + version: 2.5.6 typescript: specifier: ^5.8.3 version: 5.9.2 @@ -22,10 +22,10 @@ importers: dependencies: '@coinbase/cdp-sdk': specifier: ^1.29.0 - version: 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -35,49 +35,49 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/node': specifier: ^22.13.4 - version: 22.18.6 + version: 22.17.2 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) ../../typescript/packages/x402: dependencies: @@ -101,62 +101,62 @@ importers: version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: specifier: ^2.15.6 - version: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + version: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) zod: specifier: ^3.24.2 version: 3.25.76 devDependencies: '@coinbase/onchainkit': specifier: ^0.38.14 - version: 0.38.19(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + version: 0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) '@craftamap/esbuild-plugin-html': specifier: ^0.9.0 - version: 0.9.0(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@5.0.10) + version: 0.9.0(bufferutil@4.0.9)(esbuild@0.25.9)(utf-8-validate@5.0.10) '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/node': specifier: ^22.13.4 - version: 22.18.6 + version: 22.17.2 '@types/react': specifier: ^19 - version: 19.1.13 + version: 19.1.10 '@types/react-dom': specifier: ^19 - version: 19.1.9(@types/react@19.1.13) + version: 19.1.7(@types/react@19.1.10) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@wagmi/connectors': specifier: ^5.8.1 - version: 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76) + version: 5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) '@wagmi/core': specifier: ^2.17.1 - version: 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + version: 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) buffer: specifier: ^6.0.3 version: 6.0.3 esbuild: specifier: ^0.25.4 - version: 0.25.10 + version: 0.25.9 eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -168,31 +168,31 @@ importers: version: 19.1.1(react@19.1.1) tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) ../../typescript/packages/x402-axios: dependencies: axios: specifier: ^1.7.9 - version: 1.12.2 + version: 1.11.0 viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -202,58 +202,58 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/node': specifier: ^22.13.4 - version: 22.18.6 + version: 22.17.2 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) vitest-mock-extended: specifier: ^3.1.0 - version: 3.1.0(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1)) + version: 3.1.0(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1)) ../../typescript/packages/x402-express: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/kit': specifier: ^2.1.1 version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) @@ -262,7 +262,7 @@ importers: version: 4.21.2 viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -272,58 +272,58 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/express': specifier: ^5.0.1 version: 5.0.3 '@types/node': specifier: ^22.13.4 - version: 22.18.6 + version: 22.17.2 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) ../../typescript/packages/x402-fetch: dependencies: viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -333,64 +333,64 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/node': specifier: ^22.13.4 - version: 22.18.6 + version: 22.17.2 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) ../../typescript/packages/x402-hono: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/kit': specifier: ^2.1.1 version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) hono: specifier: ^4.7.1 - version: 4.9.8 + version: 4.9.2 viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -400,64 +400,64 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/node': specifier: ^22.13.4 - version: 22.18.6 + version: 22.17.2 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) ../../typescript/packages/x402-next: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/kit': specifier: ^2.1.1 version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) next: specifier: ^15.0.0 - version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -467,49 +467,49 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/node': specifier: ^22.13.4 - version: 22.18.6 + version: 22.17.2 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.7.3 version: 5.9.2 vite: specifier: ^6.2.6 - version: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) agent: dependencies: @@ -521,22 +521,22 @@ importers: version: 0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@coinbase/agentkit-langchain': specifier: ^0.3.0 - version: 0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + version: 0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) '@langchain/core': specifier: ^0.3.43 - version: 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + version: 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) '@langchain/langgraph': specifier: ^0.2.62 - version: 0.2.74(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76)) + version: 0.2.74(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76)) '@langchain/openai': specifier: ^0.5.2 - version: 0.5.18(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 0.5.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) dotenv: specifier: ^16.4.7 version: 16.6.1 viem: specifier: ^2.26.2 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402-fetch: specifier: workspace:* version: link:../../../typescript/packages/x402-fetch @@ -546,34 +546,34 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/node': specifier: ^22.13.4 - version: 22.18.6 + version: 22.17.2 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.7.3 version: 5.9.2 @@ -582,7 +582,7 @@ importers: dependencies: axios: specifier: ^1.7.9 - version: 1.12.2 + version: 1.11.0 dotenv: specifier: ^16.5.0 version: 16.6.1 @@ -592,31 +592,31 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.7.0 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -625,47 +625,47 @@ importers: dependencies: '@coinbase/cdp-sdk': specifier: ^1.16.0 - version: 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) axios: specifier: ^1.7.9 - version: 1.12.2 + version: 1.11.0 dotenv: specifier: ^16.5.0 version: 16.6.1 viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402-axios: specifier: workspace:* version: link:../../../../typescript/packages/x402-axios devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.7.0 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -674,32 +674,32 @@ importers: dependencies: '@hono/node-server': specifier: ^1.13.8 - version: 1.19.4(hono@4.9.8) + version: 1.19.0(hono@4.9.2) axios: specifier: ^1.7.9 - version: 1.12.2 + version: 1.11.0 dotenv: specifier: ^16.4.5 version: 16.6.1 hono: specifier: ^4.7.2 - version: 4.9.8 + version: 4.9.2 viem: specifier: ^2.23.5 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: file:../../../../typescript/packages/x402 - version: file:../../typescript/packages/x402(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: file:../../typescript/packages/x402(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) x402-axios: specifier: workspace:* version: link:../../../../typescript/packages/x402-axios devDependencies: '@types/node': specifier: ^22.13.5 - version: 22.18.6 + version: 22.17.2 tsx: specifier: ^4.19.3 - version: 4.20.5 + version: 4.20.4 clients/fetch: dependencies: @@ -712,31 +712,31 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.7.0 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -748,41 +748,41 @@ importers: version: link:../../../typescript/packages/coinbase-x402 axios: specifier: ^1.7.9 - version: 1.12.2 + version: 1.11.0 viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:* version: link:../../../typescript/packages/x402 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.7.0 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -794,25 +794,25 @@ importers: version: 0.39.0(encoding@0.1.13) '@hono/node-server': specifier: ^1.14.1 - version: 1.19.4(hono@4.9.8) + version: 1.19.0(hono@4.9.2) '@llamaindex/anthropic': specifier: ^0.3.3 - version: 0.3.25(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30) + version: 0.3.23(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30) '@types/node': specifier: ^22.15.3 - version: 22.18.6 + version: 22.17.2 axios: specifier: ^1.8.4 - version: 1.12.2 + version: 1.11.0 hono: specifier: ^4.7.7 - version: 4.9.8 + version: 4.9.2 llamaindex: specifier: ^0.10.2 version: 0.10.6(encoding@0.1.13)(tree-sitter@0.22.4)(web-tree-sitter@0.24.7)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) viem: specifier: ^2.28.3 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: ^0.2.0 version: 0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) @@ -828,25 +828,25 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -855,7 +855,7 @@ importers: version: 7.3.0(postcss@8.5.6)(typescript@5.9.2) tsx: specifier: ^4.7.0 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -874,31 +874,31 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.7.0 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -910,13 +910,13 @@ importers: version: 0.3.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@hono/node-server': specifier: ^1.11.2 - version: 1.19.4(hono@4.9.8) + version: 1.19.0(hono@4.9.2) dotenv: specifier: ^16.4.5 version: 16.6.1 hono: specifier: ^4.4.0 - version: 4.9.8 + version: 4.9.2 node-fetch: specifier: ^3.3.2 version: 3.3.2 @@ -925,7 +925,7 @@ importers: version: 2.3.2(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) viem: specifier: ^2.13.8 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: ^0.3.2 version: 0.3.7(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) @@ -938,13 +938,13 @@ importers: devDependencies: '@types/node': specifier: ^20.14.2 - version: 20.19.17 + version: 20.19.11 '@types/node-fetch': specifier: ^2.6.11 version: 2.6.13 tsx: specifier: ^4.11.0 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.4.5 version: 5.9.2 @@ -959,25 +959,25 @@ importers: dependencies: '@coinbase/onchainkit': specifier: latest - version: 1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11) + version: 0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) '@coinbase/x402': - specifier: latest - version: 0.6.4(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) + specifier: workspace:* + version: link:../../../../typescript/packages/coinbase-x402 '@farcaster/frame-sdk': specifier: ^0.0.60 - version: 0.0.60(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + version: 0.0.60(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@tanstack/react-query': specifier: ^5 - version: 5.90.2(react@19.1.1) + version: 5.85.5(react@19.1.1) '@upstash/redis': specifier: ^1.34.4 - version: 1.35.4 + version: 1.35.3 '@wagmi/core': specifier: ^2.17.1 - version: 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + version: 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) next: specifier: ^15.3.4 - version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: specifier: ^19.0.0 version: 19.1.1 @@ -989,26 +989,26 @@ importers: version: 2.6.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) viem: specifier: ^2.27.2 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: specifier: ^2.14.11 - version: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) + version: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) x402-fetch: specifier: ^0.4.1 - version: 0.4.2(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 0.4.2(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) x402-next: specifier: workspace:* version: link:../../../../typescript/packages/x402-next devDependencies: '@types/node': specifier: ^20.17.30 - version: 20.19.17 + version: 20.19.11 '@types/react': specifier: ^19 - version: 19.1.13 + version: 19.1.10 '@types/react-dom': specifier: ^19 - version: 19.1.9(@types/react@19.1.13) + version: 19.1.7(@types/react@19.1.10) eslint: specifier: ^8 version: 8.57.1 @@ -1050,7 +1050,7 @@ importers: version: 2.2.0(react@19.1.1) next: specifier: ^15.3.4 - version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: specifier: ^19.0.0 version: 19.1.1 @@ -1059,47 +1059,47 @@ importers: version: 19.1.1(react@19.1.1) viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402-next: specifier: workspace:* version: link:../../../../typescript/packages/x402-next devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@svgr/webpack': specifier: ^8.1.0 version: 8.1.0(typescript@5.9.2) '@types/node': specifier: ^20 - version: 20.19.17 + version: 20.19.11 '@types/react': specifier: ^19 - version: 19.1.13 + version: 19.1.10 '@types/react-dom': specifier: ^19 - version: 19.1.9(@types/react@19.1.13) + version: 19.1.7(@types/react@19.1.10) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-config-next: specifier: 15.1.7 - version: 15.1.7(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 15.1.7(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) postcss: specifier: ^8 version: 8.5.6 @@ -1123,7 +1123,7 @@ importers: version: 2.2.0(react@19.1.1) next: specifier: ^15.2.4 - version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: specifier: ^19.0.0 version: 19.1.1 @@ -1132,47 +1132,47 @@ importers: version: 19.1.1(react@19.1.1) viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402-next: specifier: workspace:* version: link:../../../../typescript/packages/x402-next devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@svgr/webpack': specifier: ^8.1.0 version: 8.1.0(typescript@5.9.2) '@types/node': specifier: ^20 - version: 20.19.17 + version: 20.19.11 '@types/react': specifier: ^19 - version: 19.1.13 + version: 19.1.10 '@types/react-dom': specifier: ^19 - version: 19.1.9(@types/react@19.1.13) + version: 19.1.7(@types/react@19.1.10) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-config-next: specifier: 15.1.7 - version: 15.1.7(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 15.1.7(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) postcss: specifier: ^8 version: 8.5.6 @@ -1190,13 +1190,13 @@ importers: dependencies: '@coinbase/onchainkit': specifier: latest - version: 1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11) + version: 0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@tanstack/react-query': specifier: ^5 - version: 5.90.2(react@19.1.1) + version: 5.85.5(react@19.1.1) next: specifier: ^15.3.4 - version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: specifier: ^19.0.0 version: 19.1.1 @@ -1205,23 +1205,23 @@ importers: version: 19.1.1(react@19.1.1) viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: specifier: ^2.15.6 - version: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) + version: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) x402: specifier: workspace:* version: link:../../../../typescript/packages/x402 devDependencies: '@types/node': specifier: ^20 - version: 20.19.17 + version: 20.19.11 '@types/react': specifier: ^19 - version: 19.1.13 + version: 19.1.10 '@types/react-dom': specifier: ^19 - version: 19.1.9(@types/react@19.1.13) + version: 19.1.7(@types/react@19.1.10) eslint: specifier: ^8 version: 8.57.1 @@ -1242,31 +1242,31 @@ importers: dependencies: '@coinbase/cdp-core': specifier: ^0.0.18 - version: 0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) + version: 0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) '@coinbase/cdp-hooks': specifier: ^0.0.18 - version: 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1) + version: 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1) '@coinbase/cdp-react': specifier: ^0.0.18 - version: 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1))(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1))(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@coinbase/x402': specifier: workspace:* version: link:../../../typescript/packages/coinbase-x402 '@modelcontextprotocol/sdk': specifier: ^1.15.1 - version: 1.18.1 + version: 1.17.3 '@radix-ui/react-form': specifier: ^0.1.7 - version: 0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-icons': specifier: ^1.3.2 version: 1.3.2(react@18.3.1) '@radix-ui/themes': specifier: ^3.2.1 - version: 3.2.1(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.2.1(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) axios: specifier: ^1.10.0 - version: 1.12.2 + version: 1.11.0 electron-builder: specifier: ^26.0.12 version: 26.0.12(electron-builder-squirrel-windows@26.0.12) @@ -1281,10 +1281,10 @@ importers: version: 2.0.18(react@18.3.1) turbo: specifier: ^2.5.5 - version: 2.5.8 + version: 2.5.6 viem: specifier: ^2.21.26 - version: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) winston: specifier: ^3.17.0 version: 3.17.0 @@ -1299,62 +1299,62 @@ importers: version: 3.25.76 zustand: specifier: ^5.0.6 - version: 5.0.8(@types/react@19.1.13)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) + version: 5.0.8(@types/react@19.1.10)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/node': specifier: ^24.0.13 - version: 24.5.2 + version: 24.3.0 '@types/react': specifier: ^19.1.8 - version: 19.1.13 + version: 19.1.10 '@types/react-dom': specifier: ^19.1.6 - version: 19.1.9(@types/react@19.1.13) + version: 19.1.7(@types/react@19.1.10) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@vitejs/plugin-react': specifier: ^4.7.0 - version: 4.7.0(vite@7.1.7(@types/node@24.5.2)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + version: 4.7.0(vite@7.1.3(@types/node@24.3.0)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) concurrently: specifier: ^9.2.0 - version: 9.2.1 + version: 9.2.0 electron: specifier: ^37.2.1 - version: 37.5.1 + version: 37.3.1 electron-is-dev: specifier: ^3.0.1 version: 3.0.1 eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsx: specifier: ^4.20.3 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.8.3 version: 5.9.2 vite: specifier: ^7.0.5 - version: 7.1.7(@types/node@24.5.2)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + version: 7.1.3(@types/node@24.3.0)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) servers/advanced: dependencies: @@ -1370,28 +1370,28 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/express': specifier: ^5.0.1 version: 5.0.3 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -1400,7 +1400,7 @@ importers: version: 7.3.0(postcss@8.5.6)(typescript@5.9.2) tsx: specifier: ^4.7.0 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -1409,7 +1409,7 @@ importers: dependencies: axios: specifier: ^1.11.0 - version: 1.12.2 + version: 1.11.0 dotenv: specifier: ^16.4.7 version: 16.6.1 @@ -1425,28 +1425,28 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/express': specifier: ^5.0.1 version: 5.0.3 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -1455,7 +1455,7 @@ importers: version: 7.3.0(postcss@8.5.6)(typescript@5.9.2) tsx: specifier: ^4.7.0 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -1464,38 +1464,38 @@ importers: dependencies: '@hono/node-server': specifier: ^1.13.8 - version: 1.19.4(hono@4.9.8) + version: 1.19.0(hono@4.9.2) dotenv: specifier: ^16.4.7 version: 16.6.1 hono: specifier: ^4.7.1 - version: 4.9.8 + version: 4.9.2 x402-hono: specifier: workspace:* version: link:../../../../typescript/packages/x402-hono devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -1504,7 +1504,7 @@ importers: version: 7.3.0(postcss@8.5.6)(typescript@5.9.2) tsx: specifier: ^4.7.0 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -1526,28 +1526,28 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.36.0 + version: 9.33.0 '@types/express': specifier: ^5.0.1 version: 5.0.3 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) eslint: specifier: ^9.24.0 - version: 9.36.0(jiti@1.21.7) + version: 9.33.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.36.0(jiti@1.21.7)) + version: 50.8.0(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -1556,7 +1556,7 @@ importers: version: 7.3.0(postcss@8.5.6)(typescript@5.9.2) tsx: specifier: ^4.7.0 - version: 4.20.5 + version: 4.20.4 typescript: specifier: ^5.3.0 version: 5.9.2 @@ -1575,8 +1575,8 @@ packages: '@adraffy/ens-normalize@1.10.1': resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} - '@adraffy/ens-normalize@1.11.1': - resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} @@ -1586,6 +1586,10 @@ packages: resolution: {integrity: sha512-43+Psr16UY+xh7MWn/lZyHTQiOkn0GlKtsfj9IynfCFW3jac8R3WoP6GaIqyErmeTIBq48rURZ7KFfSiRrmNTA==} engines: {node: '>=18'} + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + '@anthropic-ai/sdk@0.39.0': resolution: {integrity: sha512-eMyDIPRZbt1CCLErRCi3exlAvNkBtRe+kW5vvJyef93PmNr/clstYgHhtvmkxN82nlKgzyGPCyGxrm0JQ1ZIdg==} @@ -1603,20 +1607,20 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/types@3.893.0': - resolution: {integrity: sha512-Aht1nn5SnA0N+Tjv0dzhAY7CQbxVtmq1bBR6xI0MhG7p2XYVh1wXuKTzrldEvQWwA3odOYunAfT9aBiKZx9qIg==} + '@aws-sdk/types@3.862.0': + resolution: {integrity: sha512-Bei+RL0cDxxV+lW2UezLbCYYNeJm6Nzee0TpW0FfyTRBhH9C1XQh4+x+IClriXvgBnRquTMMYsmJfvx8iyLKrg==} engines: {node: '>=18.0.0'} '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.4': - resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} + '@babel/compat-data@7.28.0': + resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.4': - resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} + '@babel/core@7.28.3': + resolution: {integrity: sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==} engines: {node: '>=6.9.0'} '@babel/generator@7.28.3': @@ -1706,12 +1710,12 @@ packages: resolution: {integrity: sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.4': - resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + '@babel/helpers@7.28.3': + resolution: {integrity: sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.4': - resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} + '@babel/parser@7.28.3': + resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} engines: {node: '>=6.0.0'} hasBin: true @@ -1805,8 +1809,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.28.4': - resolution: {integrity: sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==} + '@babel/plugin-transform-block-scoping@7.28.0': + resolution: {integrity: sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1823,8 +1827,8 @@ packages: peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.28.4': - resolution: {integrity: sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==} + '@babel/plugin-transform-classes@7.28.3': + resolution: {integrity: sha512-DoEWC5SuxuARF2KdKmGUq3ghfPMO6ZzR12Dnp5gubwbeWJo4dbNWXJPVlwvh4Zlq6Z7YVvL8VFxeSOJgjsx4Sg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1967,8 +1971,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.28.4': - resolution: {integrity: sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==} + '@babel/plugin-transform-object-rest-spread@7.28.0': + resolution: {integrity: sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -2057,8 +2061,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.28.4': - resolution: {integrity: sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==} + '@babel/plugin-transform-regenerator@7.28.3': + resolution: {integrity: sha512-K3/M/a4+ESb5LEldjQb+XSrpY0nF+ZBFlTCbSnKaYAMfD8v33O6PMs4uYnOk19HlcsI8WMu3McdFPTiQHF/1/A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -2158,20 +2162,20 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + '@babel/runtime@7.28.3': + resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==} engines: {node: '>=6.9.0'} '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.4': - resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} + '@babel/traverse@7.28.3': + resolution: {integrity: sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.4': - resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} + '@babel/types@7.28.2': + resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} engines: {node: '>=6.9.0'} '@base-org/account@1.1.1': @@ -2207,8 +2211,8 @@ packages: '@coinbase/cdp-hooks': ^0.0.18 react: '>=18.2.0' - '@coinbase/cdp-sdk@1.38.2': - resolution: {integrity: sha512-S7+xKeZGGi+zc1PotTeQ5Pvn5a0e4ikT+iMm8pPfPjObNlDEUKLei4cmRHON1wXgql0oDXn30YKTo1LQWxXvDw==} + '@coinbase/cdp-sdk@1.36.0': + resolution: {integrity: sha512-q+8KnNEZW7mFKdCw0FsZKQ0CuxP5B0JNCkj4Ucmspjbe/EM8ZXVNh1SQMISZCu7gq9KY4bJDmpGqddwtkSGL5Q==} '@coinbase/coinbase-sdk@0.20.0': resolution: {integrity: sha512-OoMMktKbjmeEwtwQCK3kIIoX5M+hNelxAGX5Llymvw6bmyrMDaEBZ/Myga9kaLJ+7Hi5Y4jPDy4Cy2MGxxXg6w==} @@ -2219,14 +2223,6 @@ packages: react: ^18 || ^19 react-dom: ^18 || ^19 - '@coinbase/onchainkit@1.1.0': - resolution: {integrity: sha512-qoyfeGb/dwD+Rm38+3o9dIP9UcLIuzJEr5STIPXvEr5aP3aqrmFKBLRHUFVcWvLVQGkHQdpgVkWkD6a+Mh3l7A==} - peerDependencies: - react: ^19 - react-dom: ^19 - viem: ^2.27 - wagmi: ^2.16 - '@coinbase/wallet-sdk@3.9.3': resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} @@ -2236,9 +2232,6 @@ packages: '@coinbase/x402@0.3.8': resolution: {integrity: sha512-qEjxQRefXCyTfxXf4LJtB5CQZAVqjVulbol5fjcYMrA6buA1ZCq7J+l2IJVVYfeJTv70s5atLEi35xxWNobLTQ==} - '@coinbase/x402@0.6.4': - resolution: {integrity: sha512-T0tNU8/oZ64GaKC3dbGcOFHqYO0BjII/uZeC/tAS9HOqhWBvewhoa0rzPzaE8SHeKOIwX2YpbFXdG0Hyh0d4mw==} - '@colors/colors@1.6.0': resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} engines: {node: '>=0.1.90'} @@ -2249,8 +2242,8 @@ packages: peerDependencies: esbuild: '>=0.15.10' - '@csstools/color-helpers@5.1.0': - resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + '@csstools/color-helpers@5.0.2': + resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} engines: {node: '>=18'} '@csstools/css-calc@2.1.4': @@ -2260,8 +2253,8 @@ packages: '@csstools/css-parser-algorithms': ^3.0.5 '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-color-parser@3.1.0': - resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + '@csstools/css-color-parser@3.0.10': + resolution: {integrity: sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==} engines: {node: '>=18'} peerDependencies: '@csstools/css-parser-algorithms': ^3.0.5 @@ -2337,14 +2330,14 @@ packages: engines: {node: '>=14.14'} hasBin: true - '@emnapi/core@1.5.0': - resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} + '@emnapi/core@1.4.5': + resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==} - '@emnapi/runtime@1.5.0': - resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + '@emnapi/runtime@1.4.5': + resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} - '@emnapi/wasi-threads@1.1.0': - resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@emnapi/wasi-threads@1.0.4': + resolution: {integrity: sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==} '@es-joy/jsdoccomment@0.50.2': resolution: {integrity: sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==} @@ -2356,8 +2349,8 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.25.10': - resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} + '@esbuild/aix-ppc64@0.25.9': + resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -2368,8 +2361,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.10': - resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} + '@esbuild/android-arm64@0.25.9': + resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -2380,8 +2373,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.10': - resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} + '@esbuild/android-arm@0.25.9': + resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -2392,8 +2385,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.10': - resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} + '@esbuild/android-x64@0.25.9': + resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -2404,8 +2397,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.10': - resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} + '@esbuild/darwin-arm64@0.25.9': + resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -2416,8 +2409,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.10': - resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} + '@esbuild/darwin-x64@0.25.9': + resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -2428,8 +2421,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.10': - resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} + '@esbuild/freebsd-arm64@0.25.9': + resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -2440,8 +2433,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.10': - resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} + '@esbuild/freebsd-x64@0.25.9': + resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -2452,8 +2445,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.10': - resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} + '@esbuild/linux-arm64@0.25.9': + resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -2464,8 +2457,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.10': - resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} + '@esbuild/linux-arm@0.25.9': + resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -2476,8 +2469,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.10': - resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} + '@esbuild/linux-ia32@0.25.9': + resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -2488,8 +2481,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.10': - resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} + '@esbuild/linux-loong64@0.25.9': + resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -2500,8 +2493,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.10': - resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} + '@esbuild/linux-mips64el@0.25.9': + resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -2512,8 +2505,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.10': - resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} + '@esbuild/linux-ppc64@0.25.9': + resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -2524,8 +2517,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.10': - resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} + '@esbuild/linux-riscv64@0.25.9': + resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -2536,8 +2529,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.10': - resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} + '@esbuild/linux-s390x@0.25.9': + resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -2548,14 +2541,14 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.10': - resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} + '@esbuild/linux-x64@0.25.9': + resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.10': - resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} + '@esbuild/netbsd-arm64@0.25.9': + resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -2566,14 +2559,14 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.10': - resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} + '@esbuild/netbsd-x64@0.25.9': + resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.10': - resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} + '@esbuild/openbsd-arm64@0.25.9': + resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -2584,14 +2577,14 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.10': - resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} + '@esbuild/openbsd-x64@0.25.9': + resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.10': - resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} + '@esbuild/openharmony-arm64@0.25.9': + resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] @@ -2602,8 +2595,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.10': - resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} + '@esbuild/sunos-x64@0.25.9': + resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -2614,8 +2607,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.10': - resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} + '@esbuild/win32-arm64@0.25.9': + resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -2626,8 +2619,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.10': - resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} + '@esbuild/win32-ia32@0.25.9': + resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -2638,14 +2631,14 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.25.10': - resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} + '@esbuild/win32-x64@0.25.9': + resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.9.0': - resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + '@eslint-community/eslint-utils@4.7.0': + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -2678,8 +2671,8 @@ packages: resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/js@9.36.0': - resolution: {integrity: sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==} + '@eslint/js@9.33.0': + resolution: {integrity: sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -2712,15 +2705,15 @@ packages: '@farcaster/frame-sdk@0.0.60': resolution: {integrity: sha512-MHQwdFT1VPe3kS0NvnORBPb/DQXr8qpdSDgIgfrdVCB8byQ5uFELlr3gQMuFYFyLFQVXgbMl75z8O6+hvorqow==} - '@farcaster/frame-sdk@0.1.10': - resolution: {integrity: sha512-4CtBkzHIGg7NVUbVZfgy6UiIeSqn0rx7vmwvOJ4pNRQoLG5guPkHKv9vc3D515aCVSATvrZXRT97xjss5kuN+Q==} + '@farcaster/frame-sdk@0.1.9': + resolution: {integrity: sha512-r5cAKgHn4w8Q1jaCi84uKqItfNRd6h8Lk0YyQaz5kMoEIeJ4C0gXPpyqKPYP2TVDFuvaexg2KvzCO2CQdygWyQ==} engines: {node: '>=22.11.0'} - '@farcaster/miniapp-core@0.3.9': - resolution: {integrity: sha512-7k2AHYycFABUEQFHGqsuZr6P6UQOE2WO4/Qj/kQ1ydKA8QjrWxO4HjiPfnTdvqH0xOKtdavbFOV5lK5bDLkemw==} + '@farcaster/miniapp-core@0.3.8': + resolution: {integrity: sha512-LaRG1L3lxHqo5pP/E2CX9hNqusR0C8hX3QTV2+hzmQJz6IGvmSpH6Q9ivlLyDfbdqokiMFo5Y3Z1EX1zBHMEQQ==} - '@farcaster/miniapp-sdk@0.1.10': - resolution: {integrity: sha512-ueoEAH3N7hIrV+L9pXdLJZpOY1GsOuwKN7MckouSEWY98H5A7KVajyGmGSDDVzjRWpu7Vndu4NZUHoOhF4nTOA==} + '@farcaster/miniapp-sdk@0.1.9': + resolution: {integrity: sha512-hn0dlIy0JP2Hx6PgKcn9bjYwyPS/SQgYJ/a0qjzG8ZsDfUdjsMPf3yI/jicBipTml/UUoKcbqXM68fsrsbNMKA==} '@farcaster/miniapp-wagmi-connector@1.0.0': resolution: {integrity: sha512-vMRZbekUUctnAUvBFhNoEsJlujRRdxop94fDy5LrKiRR9ax0wtp8gCvLYO+LpaP2PtGs0HFpRwlHNDJWvBR8bg==} @@ -2742,21 +2735,15 @@ packages: '@floating-ui/core@1.7.3': resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} - '@floating-ui/dom@1.7.4': - resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + '@floating-ui/dom@1.7.3': + resolution: {integrity: sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==} - '@floating-ui/react-dom@2.1.6': - resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} + '@floating-ui/react-dom@2.1.5': + resolution: {integrity: sha512-HDO/1/1oH9fjj4eLgegrlH3dklZpHtUYYFiVwMUwfGvk9jWDRWqkklA2/NFScknrcNSspbV868WjXORvreDX+Q==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' - '@floating-ui/react@0.27.16': - resolution: {integrity: sha512-9O8N4SeG2z++TSM8QA/KTeKFBVCNEz/AGS7gWPJf6KFRzmRWixFRnCnkPHRDwSVZW6QPDO6uT0P2SpWNKCc9/g==} - peerDependencies: - react: '>=17.0.0' - react-dom: '>=17.0.0' - '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} @@ -2778,8 +2765,8 @@ packages: peerDependencies: react: '>= 16 || ^19.0.0-rc' - '@hono/node-server@1.19.4': - resolution: {integrity: sha512-AWKQZ/YkHUBSHeL/5Ld8FWgUs6wFf4TxGYxqp9wLZxRdFuHBpXmgOq+CuDoL4vllkZLzovCf5HBJnypiy3EtHA==} + '@hono/node-server@1.19.0': + resolution: {integrity: sha512-1k8/8OHf5VIymJEcJyVksFpT+AQ5euY0VA5hUkCnlKpD4mr8FSbvXaHblxeTTEr90OaqWzAkQaqD80qHZQKxBA==} engines: {node: '>=18.14.1'} peerDependencies: hono: ^4 @@ -2800,8 +2787,8 @@ packages: resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.7': - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} engines: {node: '>=18.18.0'} '@humanwhocodes/config-array@0.13.0': @@ -2817,132 +2804,132 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + '@humanwhocodes/retry@0.4.3': resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@img/colour@1.0.0': - resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} - engines: {node: '>=18'} - - '@img/sharp-darwin-arm64@0.34.4': - resolution: {integrity: sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==} + '@img/sharp-darwin-arm64@0.34.3': + resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.34.4': - resolution: {integrity: sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==} + '@img/sharp-darwin-x64@0.34.3': + resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.3': - resolution: {integrity: sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==} + '@img/sharp-libvips-darwin-arm64@1.2.0': + resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.3': - resolution: {integrity: sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==} + '@img/sharp-libvips-darwin-x64@1.2.0': + resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.2.3': - resolution: {integrity: sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==} + '@img/sharp-libvips-linux-arm64@1.2.0': + resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm@1.2.3': - resolution: {integrity: sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==} + '@img/sharp-libvips-linux-arm@1.2.0': + resolution: {integrity: sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-ppc64@1.2.3': - resolution: {integrity: sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==} + '@img/sharp-libvips-linux-ppc64@1.2.0': + resolution: {integrity: sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==} cpu: [ppc64] os: [linux] - '@img/sharp-libvips-linux-s390x@1.2.3': - resolution: {integrity: sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==} + '@img/sharp-libvips-linux-s390x@1.2.0': + resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-x64@1.2.3': - resolution: {integrity: sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==} + '@img/sharp-libvips-linux-x64@1.2.0': + resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.2.3': - resolution: {integrity: sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==} + '@img/sharp-libvips-linuxmusl-arm64@1.2.0': + resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.2.3': - resolution: {integrity: sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==} + '@img/sharp-libvips-linuxmusl-x64@1.2.0': + resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} cpu: [x64] os: [linux] - '@img/sharp-linux-arm64@0.34.4': - resolution: {integrity: sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==} + '@img/sharp-linux-arm64@0.34.3': + resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm@0.34.4': - resolution: {integrity: sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==} + '@img/sharp-linux-arm@0.34.3': + resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - '@img/sharp-linux-ppc64@0.34.4': - resolution: {integrity: sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==} + '@img/sharp-linux-ppc64@0.34.3': + resolution: {integrity: sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] - '@img/sharp-linux-s390x@0.34.4': - resolution: {integrity: sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==} + '@img/sharp-linux-s390x@0.34.3': + resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] - '@img/sharp-linux-x64@0.34.4': - resolution: {integrity: sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==} + '@img/sharp-linux-x64@0.34.3': + resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.4': - resolution: {integrity: sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==} + '@img/sharp-linuxmusl-arm64@0.34.3': + resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-x64@0.34.4': - resolution: {integrity: sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==} + '@img/sharp-linuxmusl-x64@0.34.3': + resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.34.4': - resolution: {integrity: sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==} + '@img/sharp-wasm32@0.34.3': + resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-win32-arm64@0.34.4': - resolution: {integrity: sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==} + '@img/sharp-win32-arm64@0.34.3': + resolution: {integrity: sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [win32] - '@img/sharp-win32-ia32@0.34.4': - resolution: {integrity: sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==} + '@img/sharp-win32-ia32@0.34.3': + resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.34.4': - resolution: {integrity: sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==} + '@img/sharp-win32-x64@0.34.3': + resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] @@ -2962,9 +2949,6 @@ packages: '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -2972,14 +2956,14 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@jridgewell/trace-mapping@0.3.30': + resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} '@jup-ag/api@6.0.44': resolution: {integrity: sha512-C6oYi+wvNi07VlmWhT8+ZDMqTJuF+MiHuNBE65cYuBH6C4l0JfwpXaj6mKazAdVqVFWgngr3s2+0tdF5nDH4tA==} - '@langchain/core@0.3.77': - resolution: {integrity: sha512-aqXHea9xfpVn6VoCq9pjujwFqrh3vw3Fgm9KFUZJ1cF7Bx5HI62DvQPw8LlRB3NB4dhwBBA1ldAVkkkd1du8nA==} + '@langchain/core@0.3.72': + resolution: {integrity: sha512-WsGWVZYnlKffj2eEfDocPNiaTRoxyYiLSQdQ7oxZvxGZBqo/90vpjbC33UGK1uPNBM4kT+pkdaol/MnvKUh8TQ==} engines: {node: '>=18'} '@langchain/langgraph-checkpoint@0.0.18': @@ -2988,8 +2972,8 @@ packages: peerDependencies: '@langchain/core': '>=0.2.31 <0.4.0' - '@langchain/langgraph-sdk@0.0.112': - resolution: {integrity: sha512-/9W5HSWCqYgwma6EoOspL4BGYxGxeJP6lIquPSF4FA0JlKopaUv58ucZC3vAgdJyCgg6sorCIV/qg7SGpEcCLw==} + '@langchain/langgraph-sdk@0.0.109': + resolution: {integrity: sha512-UpjL0c681CJqvKxgWD8o9fwUXRZzcDfsz8EcJ2PkXFxQFKRLe4QKZMtBr4OKFTR94pJtlOuTVla4OV5I5w+mdQ==} peerDependencies: '@langchain/core': '>=0.2.31 <0.4.0' react: ^18 || ^19 @@ -3024,10 +3008,10 @@ packages: '@lit/reactive-element@2.1.1': resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} - '@llamaindex/anthropic@0.3.25': - resolution: {integrity: sha512-qrRh2ReRUY/pwApZjaX6gpUQRZxx16UcMoZLuBWP+pySzEr0jvZSq9guYmLRbQMv1xgr3SWoPjulMR+AEh7Dgg==} + '@llamaindex/anthropic@0.3.23': + resolution: {integrity: sha512-4qvRZ8cBasRdLliN5KMi1diSn+9lNFTOaUroCSwMAivRl97R1HVd+ZRfXqmorkoB2aYpG4rAZ9ycIgRNUctX8g==} peerDependencies: - '@llamaindex/core': 0.6.22 + '@llamaindex/core': 0.6.20 '@llamaindex/env': 0.1.30 '@llamaindex/cloud@4.0.7': @@ -3121,11 +3105,8 @@ packages: resolution: {integrity: sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==} engines: {node: '>=12.0.0'} - '@metamask/sdk-analytics@0.0.5': - resolution: {integrity: sha512-fDah+keS1RjSUlC8GmYXvx6Y26s3Ax1U9hGpWb6GSY5SAdmTSIqp2CvYy6yW0WgLhnYhW+6xERuD0eVqV63QIQ==} - - '@metamask/sdk-communication-layer@0.33.1': - resolution: {integrity: sha512-0bI9hkysxcfbZ/lk0T2+aKVo1j0ynQVTuB3sJ5ssPWlz+Z3VwveCkP1O7EVu1tsVVCb0YV5WxK9zmURu2FIiaA==} + '@metamask/sdk-communication-layer@0.32.0': + resolution: {integrity: sha512-dmj/KFjMi1fsdZGIOtbhxdg3amxhKL/A5BqSU4uh/SyDKPub/OT+x5pX8bGjpTL1WPWY/Q0OIlvFyX3VWnT06Q==} peerDependencies: cross-fetch: ^4.0.0 eciesjs: '*' @@ -3133,18 +3114,18 @@ packages: readable-stream: ^3.6.2 socket.io-client: ^4.5.1 - '@metamask/sdk-install-modal-web@0.32.1': - resolution: {integrity: sha512-MGmAo6qSjf1tuYXhCu2EZLftq+DSt5Z7fsIKr2P+lDgdTPWgLfZB1tJKzNcwKKOdf6q9Qmmxn7lJuI/gq5LrKw==} + '@metamask/sdk-install-modal-web@0.32.0': + resolution: {integrity: sha512-TFoktj0JgfWnQaL3yFkApqNwcaqJ+dw4xcnrJueMP3aXkSNev2Ido+WVNOg4IIMxnmOrfAC9t0UJ0u/dC9MjOQ==} - '@metamask/sdk@0.33.1': - resolution: {integrity: sha512-1mcOQVGr9rSrVcbKPNVzbZ8eCl1K0FATsYH3WJ/MH4WcZDWGECWrXJPNMZoEAkLxWiMe8jOQBumg2pmcDa9zpQ==} + '@metamask/sdk@0.32.0': + resolution: {integrity: sha512-WmGAlP1oBuD9hk4CsdlG1WJFuPtYJY+dnTHJMeCyohTWD2GgkcLMUUuvu9lO1/NVzuOoSi1OrnjbuY1O/1NZ1g==} '@metamask/superstruct@3.2.1': resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==} engines: {node: '>=16.0.0'} - '@metamask/utils@11.8.1': - resolution: {integrity: sha512-DIbsNUyqWLFgqJlZxi1OOCMYvI23GqFCvNJAtzv8/WXWzJfnJnvp1M24j7VvUe3URBi3S86UgQ7+7aWU9p/cnQ==} + '@metamask/utils@11.4.2': + resolution: {integrity: sha512-TygCcGmUbhmpxjYMm+mx68kRiJ80jYV54/Aa8gUFBv4cTX7ulX2XZKr8CJoJAw3K3FN5ZvCRmU0IzWZFaonwhA==} engines: {node: ^18.18 || ^20.14 || >=22} '@metamask/utils@5.0.2': @@ -3159,15 +3140,15 @@ packages: resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} engines: {node: '>=16.0.0'} - '@modelcontextprotocol/sdk@1.18.1': - resolution: {integrity: sha512-d//GE8/Yh7aC3e7p+kZG8JqqEAwwDUmAfvH1quogtbk+ksS6E0RR6toKKESPYYZVre0meqkJb27zb+dhqE9Sgw==} + '@modelcontextprotocol/sdk@1.17.3': + resolution: {integrity: sha512-JPwUKWSsbzx+DLFznf/QZ32Qa+ptfbUlHhRLrBQBAFu9iI1iYvizM4p+zhhRDceSsPutXp4z+R/HPVphlIiclg==} engines: {node: '>=18'} '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - '@next/env@15.5.4': - resolution: {integrity: sha512-27SQhYp5QryzIT5uO8hq99C69eLQ7qkzkDPsk3N+GuS2XgOgoYEeOav7Pf8Tn4drECOVDsDg8oj+/DVy8qQL2A==} + '@next/env@15.5.0': + resolution: {integrity: sha512-sDaprBAfzCQiOgo2pO+LhnV0Wt2wBgartjrr+dpcTORYVnnXD0gwhHhiiyIih9hQbq+JnbqH4odgcFWhqCGidw==} '@next/eslint-plugin-next@15.1.7': resolution: {integrity: sha512-kRP7RjSxfTO13NE317ek3mSGzoZlI33nc/i5hs1KaWpK+egs85xg0DJ4p32QEiHnR0mVjuUfhRIun7awqfL7pQ==} @@ -3175,50 +3156,50 @@ packages: '@next/eslint-plugin-next@15.3.3': resolution: {integrity: sha512-VKZJEiEdpKkfBmcokGjHu0vGDG+8CehGs90tBEy/IDoDDKGngeyIStt2MmE5FYNyU9BhgR7tybNWTAJY/30u+Q==} - '@next/swc-darwin-arm64@15.5.4': - resolution: {integrity: sha512-nopqz+Ov6uvorej8ndRX6HlxCYWCO3AHLfKK2TYvxoSB2scETOcfm/HSS3piPqc3A+MUgyHoqE6je4wnkjfrOA==} + '@next/swc-darwin-arm64@15.5.0': + resolution: {integrity: sha512-v7Jj9iqC6enxIRBIScD/o0lH7QKvSxq2LM8UTyqJi+S2w2QzhMYjven4vgu/RzgsdtdbpkyCxBTzHl/gN5rTRg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@15.5.4': - resolution: {integrity: sha512-QOTCFq8b09ghfjRJKfb68kU9k2K+2wsC4A67psOiMn849K9ZXgCSRQr0oVHfmKnoqCbEmQWG1f2h1T2vtJJ9mA==} + '@next/swc-darwin-x64@15.5.0': + resolution: {integrity: sha512-s2Nk6ec+pmYmAb/utawuURy7uvyYKDk+TRE5aqLRsdnj3AhwC9IKUBmhfnLmY/+P+DnwqpeXEFIKe9tlG0p6CA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@15.5.4': - resolution: {integrity: sha512-eRD5zkts6jS3VfE/J0Kt1VxdFqTnMc3QgO5lFE5GKN3KDI/uUpSyK3CjQHmfEkYR4wCOl0R0XrsjpxfWEA++XA==} + '@next/swc-linux-arm64-gnu@15.5.0': + resolution: {integrity: sha512-mGlPJMZReU4yP5fSHjOxiTYvZmwPSWn/eF/dcg21pwfmiUCKS1amFvf1F1RkLHPIMPfocxLViNWFvkvDB14Isg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.5.4': - resolution: {integrity: sha512-TOK7iTxmXFc45UrtKqWdZ1shfxuL4tnVAOuuJK4S88rX3oyVV4ZkLjtMT85wQkfBrOOvU55aLty+MV8xmcJR8A==} + '@next/swc-linux-arm64-musl@15.5.0': + resolution: {integrity: sha512-biWqIOE17OW/6S34t1X8K/3vb1+svp5ji5QQT/IKR+VfM3B7GvlCwmz5XtlEan2ukOUf9tj2vJJBffaGH4fGRw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@15.5.4': - resolution: {integrity: sha512-7HKolaj+481FSW/5lL0BcTkA4Ueam9SPYWyN/ib/WGAFZf0DGAN8frNpNZYFHtM4ZstrHZS3LY3vrwlIQfsiMA==} + '@next/swc-linux-x64-gnu@15.5.0': + resolution: {integrity: sha512-zPisT+obYypM/l6EZ0yRkK3LEuoZqHaSoYKj+5jiD9ESHwdr6QhnabnNxYkdy34uCigNlWIaCbjFmQ8FY5AlxA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.5.4': - resolution: {integrity: sha512-nlQQ6nfgN0nCO/KuyEUwwOdwQIGjOs4WNMjEUtpIQJPR2NUfmGpW2wkJln1d4nJ7oUzd1g4GivH5GoEPBgfsdw==} + '@next/swc-linux-x64-musl@15.5.0': + resolution: {integrity: sha512-+t3+7GoU9IYmk+N+FHKBNFdahaReoAktdOpXHFIPOU1ixxtdge26NgQEEkJkCw2dHT9UwwK5zw4mAsURw4E8jA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@15.5.4': - resolution: {integrity: sha512-PcR2bN7FlM32XM6eumklmyWLLbu2vs+D7nJX8OAIoWy69Kef8mfiN4e8TUv2KohprwifdpFKPzIP1njuCjD0YA==} + '@next/swc-win32-arm64-msvc@15.5.0': + resolution: {integrity: sha512-d8MrXKh0A+c9DLiy1BUFwtg3Hu90Lucj3k6iKTUdPOv42Ve2UiIG8HYi3UAb8kFVluXxEfdpCoPPCSODk5fDcw==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@15.5.4': - resolution: {integrity: sha512-1ur2tSHZj8Px/KMAthmuI9FMp/YFusMMGoRNJaRZMOlSkgvLjzosSdQI0cJAKogdHl3qXUQKL9MGaYvKwA7DXg==} + '@next/swc-win32-x64-msvc@15.5.0': + resolution: {integrity: sha512-Fe1tGHxOWEyQjmygWkkXSwhFcTJuimrNu52JEuwItrKJVV4iRjbWp9I7zZjwqtiNnQmxoEvoisn8wueFLrNpvQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -3245,8 +3226,8 @@ packages: resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} engines: {node: ^14.21.3 || >=16} - '@noble/curves@1.9.1': - resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} + '@noble/curves@1.9.6': + resolution: {integrity: sha512-GIKz/j99FRthB8icyJQA51E8Uk5hXmdyThjgQXRKiv9h0zeRlzSCLIzFw6K1LotZ3XuB7yzlf76qk7uBmTdFqA==} engines: {node: ^14.21.3 || >=16} '@noble/curves@1.9.7': @@ -3314,14 +3295,14 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@privy-io/api-base@1.7.0': - resolution: {integrity: sha512-ji6ARQAAuW/FzRTgft9NCjRuouWX9t+J7JMmvLPsnXQJDFEV9mqh4sWXZhQ8ddTq/iDZ4z/yz1ORJqN8bYAi4Q==} + '@privy-io/api-base@1.6.0': + resolution: {integrity: sha512-ftlqjFw0Ww7Xn6Ad/1kEUsXRfKqNdmJYKat4ryJl2uPh60QXXlPfnf4y17dDFHJlnVb7qY10cCvKVz5ev5gAeg==} - '@privy-io/public-api@2.45.2': - resolution: {integrity: sha512-TSuaFq65PPInb0CBJ9dO/vLh4u4oWXVpv5KxShbVsuaArZ8lig+Orl/HUR1Hri6643zXoBqWlWx9wDt4MQvz9A==} + '@privy-io/public-api@2.43.1': + resolution: {integrity: sha512-zhGBTghZiwnqdA4YvrXXM7fsz3fWUltSkxNdnQTqKGb/IfV8aZ14ryuWvD4v5oPJGtqVcwKRfdDmW8TMPGZHog==} - '@privy-io/server-auth@1.32.5': - resolution: {integrity: sha512-e087vImrFHP4yAMx8alyCeCm6gk2JG/q7eSklFoST5mPTUV9TGKx7XNIyKOQQHxwKMpk5SBVIlkyJcqg3CuxSw==} + '@privy-io/server-auth@1.31.1': + resolution: {integrity: sha512-w0DT0VZCPcXa/Mxqzo7fhXoInX5i4J5BgvzjNsdtMuovgR790kMx/9+K/rSlgtQ/25/B7oDjoIk/f8kd5Ps6mA==} peerDependencies: ethers: ^6 viem: ^2.24.1 @@ -4074,113 +4055,103 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rollup/rollup-android-arm-eabi@4.52.2': - resolution: {integrity: sha512-o3pcKzJgSGt4d74lSZ+OCnHwkKBeAbFDmbEm5gg70eA8VkyCuC/zV9TwBnmw6VjDlRdF4Pshfb+WE9E6XY1PoQ==} + '@rollup/rollup-android-arm-eabi@4.46.4': + resolution: {integrity: sha512-B2wfzCJ+ps/OBzRjeds7DlJumCU3rXMxJJS1vzURyj7+KBHGONm7c9q1TfdBl4vCuNMkDvARn3PBl2wZzuR5mw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.52.2': - resolution: {integrity: sha512-cqFSWO5tX2vhC9hJTK8WAiPIm4Q8q/cU8j2HQA0L3E1uXvBYbOZMhE2oFL8n2pKB5sOCHY6bBuHaRwG7TkfJyw==} + '@rollup/rollup-android-arm64@4.46.4': + resolution: {integrity: sha512-FGJYXvYdn8Bs6lAlBZYT5n+4x0ciEp4cmttsvKAZc/c8/JiPaQK8u0c/86vKX8lA7OY/+37lIQSe0YoAImvBAA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.52.2': - resolution: {integrity: sha512-vngduywkkv8Fkh3wIZf5nFPXzWsNsVu1kvtLETWxTFf/5opZmflgVSeLgdHR56RQh71xhPhWoOkEBvbehwTlVA==} + '@rollup/rollup-darwin-arm64@4.46.4': + resolution: {integrity: sha512-/9qwE/BM7ATw/W/OFEMTm3dmywbJyLQb4f4v5nmOjgYxPIGpw7HaxRi6LnD4Pjn/q7k55FGeHe1/OD02w63apA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.52.2': - resolution: {integrity: sha512-h11KikYrUCYTrDj6h939hhMNlqU2fo/X4NB0OZcys3fya49o1hmFaczAiJWVAFgrM1NCP6RrO7lQKeVYSKBPSQ==} + '@rollup/rollup-darwin-x64@4.46.4': + resolution: {integrity: sha512-QkWfNbeRuzFnv2d0aPlrzcA3Ebq2mE8kX/5Pl7VdRShbPBjSnom7dbT8E3Jmhxo2RL784hyqGvR5KHavCJQciw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.52.2': - resolution: {integrity: sha512-/eg4CI61ZUkLXxMHyVlmlGrSQZ34xqWlZNW43IAU4RmdzWEx0mQJ2mN/Cx4IHLVZFL6UBGAh+/GXhgvGb+nVxw==} + '@rollup/rollup-freebsd-arm64@4.46.4': + resolution: {integrity: sha512-+ToyOMYnSfV8D+ckxO6NthPln/PDNp1P6INcNypfZ7muLmEvPKXqduUiD8DlJpMMT8LxHcE5W0dK9kXfJke9Zw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.52.2': - resolution: {integrity: sha512-QOWgFH5X9+p+S1NAfOqc0z8qEpJIoUHf7OWjNUGOeW18Mx22lAUOiA9b6r2/vpzLdfxi/f+VWsYjUOMCcYh0Ng==} + '@rollup/rollup-freebsd-x64@4.46.4': + resolution: {integrity: sha512-cGT6ey/W+sje6zywbLiqmkfkO210FgRz7tepWAzzEVgQU8Hn91JJmQWNqs55IuglG8sJdzk7XfNgmGRtcYlo1w==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.52.2': - resolution: {integrity: sha512-kDWSPafToDd8LcBYd1t5jw7bD5Ojcu12S3uT372e5HKPzQt532vW+rGFFOaiR0opxePyUkHrwz8iWYEyH1IIQA==} + '@rollup/rollup-linux-arm-gnueabihf@4.46.4': + resolution: {integrity: sha512-9fhTJyOb275w5RofPSl8lpr4jFowd+H4oQKJ9XTYzD1JWgxdZKE8bA6d4npuiMemkecQOcigX01FNZNCYnQBdA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.52.2': - resolution: {integrity: sha512-gKm7Mk9wCv6/rkzwCiUC4KnevYhlf8ztBrDRT9g/u//1fZLapSRc+eDZj2Eu2wpJ+0RzUKgtNijnVIB4ZxyL+w==} + '@rollup/rollup-linux-arm-musleabihf@4.46.4': + resolution: {integrity: sha512-+6kCIM5Zjvz2HwPl/udgVs07tPMIp1VU2Y0c72ezjOvSvEfAIWsUgpcSDvnC7g9NrjYR6X9bZT92mZZ90TfvXw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.52.2': - resolution: {integrity: sha512-66lA8vnj5mB/rtDNwPgrrKUOtCLVQypkyDa2gMfOefXK6rcZAxKLO9Fy3GkW8VkPnENv9hBkNOFfGLf6rNKGUg==} + '@rollup/rollup-linux-arm64-gnu@4.46.4': + resolution: {integrity: sha512-SWuXdnsayCZL4lXoo6jn0yyAj7TTjWE4NwDVt9s7cmu6poMhtiras5c8h6Ih6Y0Zk6Z+8t/mLumvpdSPTWub2Q==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.52.2': - resolution: {integrity: sha512-s+OPucLNdJHvuZHuIz2WwncJ+SfWHFEmlC5nKMUgAelUeBUnlB4wt7rXWiyG4Zn07uY2Dd+SGyVa9oyLkVGOjA==} + '@rollup/rollup-linux-arm64-musl@4.46.4': + resolution: {integrity: sha512-vDknMDqtMhrrroa5kyX6tuC0aRZZlQ+ipDfbXd2YGz5HeV2t8HOl/FDAd2ynhs7Ki5VooWiiZcCtxiZ4IjqZwQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.52.2': - resolution: {integrity: sha512-8wTRM3+gVMDLLDdaT6tKmOE3lJyRy9NpJUS/ZRWmLCmOPIJhVyXwjBo+XbrrwtV33Em1/eCTd5TuGJm4+DmYjw==} + '@rollup/rollup-linux-loongarch64-gnu@4.46.4': + resolution: {integrity: sha512-mCBkjRZWhvjtl/x+Bd4fQkWZT8canStKDxGrHlBiTnZmJnWygGcvBylzLVCZXka4dco5ymkWhZlLwKCGFF4ivw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.52.2': - resolution: {integrity: sha512-6yqEfgJ1anIeuP2P/zhtfBlDpXUb80t8DpbYwXQ3bQd95JMvUaqiX+fKqYqUwZXqdJDd8xdilNtsHM2N0cFm6A==} + '@rollup/rollup-linux-ppc64-gnu@4.46.4': + resolution: {integrity: sha512-YMdz2phOTFF+Z66dQfGf0gmeDSi5DJzY5bpZyeg9CPBkV9QDzJ1yFRlmi/j7WWRf3hYIWrOaJj5jsfwgc8GTHQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.52.2': - resolution: {integrity: sha512-sshYUiYVSEI2B6dp4jMncwxbrUqRdNApF2c3bhtLAU0qA8Lrri0p0NauOsTWh3yCCCDyBOjESHMExonp7Nzc0w==} + '@rollup/rollup-linux-riscv64-gnu@4.46.4': + resolution: {integrity: sha512-r0WKLSfFAK8ucG024v2yiLSJMedoWvk8yWqfNICX28NHDGeu3F/wBf8KG6mclghx4FsLePxJr/9N8rIj1PtCnw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.52.2': - resolution: {integrity: sha512-duBLgd+3pqC4MMwBrKkFxaZerUxZcYApQVC5SdbF5/e/589GwVvlRUnyqMFbM8iUSb1BaoX/3fRL7hB9m2Pj8Q==} + '@rollup/rollup-linux-riscv64-musl@4.46.4': + resolution: {integrity: sha512-IaizpPP2UQU3MNyPH1u0Xxbm73D+4OupL0bjo4Hm0496e2wg3zuvoAIhubkD1NGy9fXILEExPQy87mweujEatA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.52.2': - resolution: {integrity: sha512-tzhYJJidDUVGMgVyE+PmxENPHlvvqm1KILjjZhB8/xHYqAGeizh3GBGf9u6WdJpZrz1aCpIIHG0LgJgH9rVjHQ==} + '@rollup/rollup-linux-s390x-gnu@4.46.4': + resolution: {integrity: sha512-aCM29orANR0a8wk896p6UEgIfupReupnmISz6SUwMIwTGaTI8MuKdE0OD2LvEg8ondDyZdMvnaN3bW4nFbATPA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.52.2': - resolution: {integrity: sha512-opH8GSUuVcCSSyHHcl5hELrmnk4waZoVpgn/4FDao9iyE4WpQhyWJ5ryl5M3ocp4qkRuHfyXnGqg8M9oKCEKRA==} + '@rollup/rollup-linux-x64-gnu@4.46.4': + resolution: {integrity: sha512-0Xj1vZE3cbr/wda8d/m+UeuSL+TDpuozzdD4QaSzu/xSOMK0Su5RhIkF7KVHFQsobemUNHPLEcYllL7ZTCP/Cg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.52.2': - resolution: {integrity: sha512-LSeBHnGli1pPKVJ79ZVJgeZWWZXkEe/5o8kcn23M8eMKCUANejchJbF/JqzM4RRjOJfNRhKJk8FuqL1GKjF5oQ==} + '@rollup/rollup-linux-x64-musl@4.46.4': + resolution: {integrity: sha512-kM/orjpolfA5yxsx84kI6bnK47AAZuWxglGKcNmokw2yy9i5eHY5UAjcX45jemTJnfHAWo3/hOoRqEeeTdL5hw==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.52.2': - resolution: {integrity: sha512-uPj7MQ6/s+/GOpolavm6BPo+6CbhbKYyZHUDvZ/SmJM7pfDBgdGisFX3bY/CBDMg2ZO4utfhlApkSfZ92yXw7Q==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.52.2': - resolution: {integrity: sha512-Z9MUCrSgIaUeeHAiNkm3cQyst2UhzjPraR3gYYfOjAuZI7tcFRTOD+4cHLPoS/3qinchth+V56vtqz1Tv+6KPA==} + '@rollup/rollup-win32-arm64-msvc@4.46.4': + resolution: {integrity: sha512-cNLH4psMEsWKILW0isbpQA2OvjXLbKvnkcJFmqAptPQbtLrobiapBJVj6RoIvg6UXVp5w0wnIfd/Q56cNpF+Ew==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.52.2': - resolution: {integrity: sha512-+GnYBmpjldD3XQd+HMejo+0gJGwYIOfFeoBQv32xF/RUIvccUz20/V6Otdv+57NE70D5pa8W/jVGDoGq0oON4A==} + '@rollup/rollup-win32-ia32-msvc@4.46.4': + resolution: {integrity: sha512-OiEa5lRhiANpv4SfwYVgQ3opYWi/QmPDC5ve21m8G9pf6ZO+aX1g2EEF1/IFaM1xPSP7mK0msTRXlPs6mIagkg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.52.2': - resolution: {integrity: sha512-ApXFKluSB6kDQkAqZOKXBjiaqdF1BlKi+/eqnYe9Ee7U2K3pUDKsIyr8EYm/QDHTJIM+4X+lI0gJc3TTRhd+dA==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.52.2': - resolution: {integrity: sha512-ARz+Bs8kY6FtitYM96PqPEVvPXqEZmPZsSkXvyX19YzDqkCaIlhCieLLMI5hxO9SRZ2XtCtm8wxhy0iJ2jxNfw==} + '@rollup/rollup-win32-x64-msvc@4.46.4': + resolution: {integrity: sha512-IKL9mewGZ5UuuX4NQlwOmxPyqielvkAPUS2s1cl6yWjjQvyN3h5JTdVFGD5Jr5xMjRC8setOfGQDVgX8V+dkjg==} cpu: [x64] os: [win32] @@ -4235,8 +4206,8 @@ packages: resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} engines: {node: '>=14.0.0'} - '@smithy/types@4.5.0': - resolution: {integrity: sha512-RkUpIOsVlAwUIZXO1dsz8Zm+N72LClFfsNqf173catVlvRZiwPy0x2u0JLEA4byreOPKDZPGjmPDylMoP8ZJRg==} + '@smithy/types@4.3.2': + resolution: {integrity: sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw==} engines: {node: '>=18.0.0'} '@smithy/util-buffer-from@2.2.0': @@ -4512,8 +4483,8 @@ packages: peerDependencies: '@solana/web3.js': ^1.95.3 - '@solana/spl-token@0.4.14': - resolution: {integrity: sha512-u09zr96UBpX4U685MnvQsNzlvw9TiY005hk1vJmJr7gMJldoPG1eYU5/wNEyOA5lkMLiR/gOi9SFD4MefOYEsA==} + '@solana/spl-token@0.4.13': + resolution: {integrity: sha512-cite/pYWQZZVvLbg5lsodSovbetK/eA24gaR0eeUeMuBAMNrT8XFCwaygKy0N2WSg3gSyjjNpIeAGBAKZaY/1w==} engines: {node: '>=16'} peerDependencies: '@solana/web3.js': ^1.95.5 @@ -4657,11 +4628,11 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} - '@tanstack/query-core@5.90.2': - resolution: {integrity: sha512-k/TcR3YalnzibscALLwxeiLUub6jN5EDLwKDiO7q5f4ICEoptJ+n9+7vcEFy5/x/i6Q+Lb/tXrsKCggf5uQJXQ==} + '@tanstack/query-core@5.85.5': + resolution: {integrity: sha512-KO0WTob4JEApv69iYp1eGvfMSUkgw//IpMnq+//cORBzXf0smyRwPLrUvEe5qtAEGjwZTXrjxg+oJNP/C00t6w==} - '@tanstack/react-query@5.90.2': - resolution: {integrity: sha512-CLABiR+h5PYfOWr/z+vWFt5VsOA2ekQeRQBFSKlcoW6Ndx/f8rfyVmq4LbgOM4GG2qtxAxjLYLOpCNTYm4uKzw==} + '@tanstack/react-query@5.85.5': + resolution: {integrity: sha512-/X4EFNcnPiSs8wM2v+b6DqS5mmGeuJQvxBglmDxl6ZQb5V26ouD2SJYAcC3VjbNwqhY2zjxVD15rDA5nGbMn3A==} peerDependencies: react: ^18 || ^19 @@ -4673,8 +4644,8 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@tybys/wasm-util@0.10.0': + resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==} '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -4748,20 +4719,20 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@18.19.127': - resolution: {integrity: sha512-gSjxjrnKXML/yo0BO099uPixMqfpJU0TKYjpfLU7TrtA2WWDki412Np/RSTPRil1saKBhvVVKzVx/p/6p94nVA==} + '@types/node@18.19.123': + resolution: {integrity: sha512-K7DIaHnh0mzVxreCR9qwgNxp3MH9dltPNIEddW9MYUlcKAzm+3grKNSTe2vCJHI1FaLpvpL5JGJrz1UZDKYvDg==} - '@types/node@20.19.17': - resolution: {integrity: sha512-gfehUI8N1z92kygssiuWvLiwcbOB3IRktR6hTDgJlXMYh5OvkPSRmgfoBUmfZt+vhwJtX7v1Yw4KvvAf7c5QKQ==} + '@types/node@20.19.11': + resolution: {integrity: sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==} - '@types/node@22.18.6': - resolution: {integrity: sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==} + '@types/node@22.17.2': + resolution: {integrity: sha512-gL6z5N9Jm9mhY+U2KXZpteb+09zyffliRkZyZOHODGATyC5B1Jt/7TzuuiLkFsSUMLbS1OLmlj/E+/3KF4Q/4w==} '@types/node@22.7.5': resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} - '@types/node@24.5.2': - resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} + '@types/node@24.3.0': + resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==} '@types/plist@3.0.5': resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} @@ -4772,13 +4743,13 @@ packages: '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/react-dom@19.1.9': - resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} + '@types/react-dom@19.1.7': + resolution: {integrity: sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==} peerDependencies: '@types/react': ^19.0.0 - '@types/react@19.1.13': - resolution: {integrity: sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==} + '@types/react@19.1.10': + resolution: {integrity: sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg==} '@types/responselike@1.0.3': resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} @@ -4819,63 +4790,63 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.44.1': - resolution: {integrity: sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==} + '@typescript-eslint/eslint-plugin@8.40.0': + resolution: {integrity: sha512-w/EboPlBwnmOBtRbiOvzjD+wdiZdgFeo17lkltrtn7X37vagKKWJABvyfsJXTlHe6XBzugmYgd4A4nW+k8Mixw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.44.1 + '@typescript-eslint/parser': ^8.40.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.44.1': - resolution: {integrity: sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==} + '@typescript-eslint/parser@8.40.0': + resolution: {integrity: sha512-jCNyAuXx8dr5KJMkecGmZ8KI61KBUhkCob+SD+C+I5+Y1FWI2Y3QmY4/cxMCC5WAsZqoEtEETVhUiUMIGCf6Bw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.44.1': - resolution: {integrity: sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==} + '@typescript-eslint/project-service@8.40.0': + resolution: {integrity: sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.44.1': - resolution: {integrity: sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==} + '@typescript-eslint/scope-manager@8.40.0': + resolution: {integrity: sha512-y9ObStCcdCiZKzwqsE8CcpyuVMwRouJbbSrNuThDpv16dFAj429IkM6LNb1dZ2m7hK5fHyzNcErZf7CEeKXR4w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.44.1': - resolution: {integrity: sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==} + '@typescript-eslint/tsconfig-utils@8.40.0': + resolution: {integrity: sha512-jtMytmUaG9d/9kqSl/W3E3xaWESo4hFDxAIHGVW/WKKtQhesnRIJSAJO6XckluuJ6KDB5woD1EiqknriCtAmcw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.44.1': - resolution: {integrity: sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==} + '@typescript-eslint/type-utils@8.40.0': + resolution: {integrity: sha512-eE60cK4KzAc6ZrzlJnflXdrMqOBaugeukWICO2rB0KNvwdIMaEaYiywwHMzA1qFpTxrLhN9Lp4E/00EgWcD3Ow==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.44.1': - resolution: {integrity: sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==} + '@typescript-eslint/types@8.40.0': + resolution: {integrity: sha512-ETdbFlgbAmXHyFPwqUIYrfc12ArvpBhEVgGAxVYSwli26dn8Ko+lIo4Su9vI9ykTZdJn+vJprs/0eZU0YMAEQg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.44.1': - resolution: {integrity: sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==} + '@typescript-eslint/typescript-estree@8.40.0': + resolution: {integrity: sha512-k1z9+GJReVVOkc1WfVKs1vBrR5MIKKbdAjDTPvIK3L8De6KbFfPFt6BKpdkdk7rZS2GtC/m6yI5MYX+UsuvVYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.44.1': - resolution: {integrity: sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==} + '@typescript-eslint/utils@8.40.0': + resolution: {integrity: sha512-Cgzi2MXSZyAUOY+BFwGs17s7ad/7L+gKt6Y8rAVVWS+7o6wrjeFN4nVfTpbE25MNcxyJ+iYUXflbs2xR9h4UBg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.44.1': - resolution: {integrity: sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==} + '@typescript-eslint/visitor-keys@8.40.0': + resolution: {integrity: sha512-8CZ47QwalyRjsypfwnbI3hKy5gJDPmrkLjkgMxhi0+DZZ2QNx2naS6/hWoVYUHU7LU2zleF68V9miaVZvhFfTA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -4976,8 +4947,8 @@ packages: cpu: [x64] os: [win32] - '@upstash/redis@1.35.4': - resolution: {integrity: sha512-WE1ZnhFyBiIjTDW13GbO6JjkiMVVjw5VsvS8ENmvvJsze/caMQ5paxVD44+U68IUVmkXcbsLSoE+VIYsHtbQEw==} + '@upstash/redis@1.35.3': + resolution: {integrity: sha512-hSjv66NOuahW3MisRGlSgoszU2uONAY2l5Qo3Sae8OT3/Tng9K+2/cBRuyPBX8egwEGcNNCF9+r0V6grNnhL+w==} '@vitejs/plugin-react@4.7.0': resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} @@ -5014,18 +4985,18 @@ packages: '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@wagmi/connectors@5.11.1': - resolution: {integrity: sha512-2jbx6z8rk/srQdbnKF2viCc3ke02HSMQU5EZS90jWoJ1t4+Fn3+bhphgVeJ1LnVFWsuEBSuIcY63iic4emwGfg==} + '@wagmi/connectors@5.9.4': + resolution: {integrity: sha512-k/GSdYS6nuL0zLq5H7XasPmKr3Gnvplq+yQhTfRBu/o5Bh+B3aH3Jfq1lUh+t3z5kQcyKJIXw/bZIZ7lVS7UhA==} peerDependencies: - '@wagmi/core': 2.21.1 + '@wagmi/core': 2.19.0 typescript: '>=5.0.4' viem: 2.x peerDependenciesMeta: typescript: optional: true - '@wagmi/core@2.21.1': - resolution: {integrity: sha512-uG0Cujm24acrFYqbi1RGw9MRMLTGVKvyv5OAJT+2pkcasM9PP8eJCzhlvUxK9IYVXXnbaAT8JX/rXEurOSM6mg==} + '@wagmi/core@2.19.0': + resolution: {integrity: sha512-lI57q6refAtNU6xnk/oyOpbEtEiwQ6g4rR+C9FEx8Gn2hZlfoyyksndrl6hIKlMBK+UkkKso3VwR5DI65j/5XQ==} peerDependencies: '@tanstack/query-core': '>=5.0.0' typescript: '>=5.0.4' @@ -5153,22 +5124,11 @@ packages: zod: optional: true - abitype@1.1.0: - resolution: {integrity: sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==} - peerDependencies: - typescript: '>=5.0.4' - zod: ^3.22.0 || ^4.0.0 - peerDependenciesMeta: - typescript: - optional: true - zod: - optional: true - - abitype@1.1.1: - resolution: {integrity: sha512-Loe5/6tAgsBukY95eGaPSDmQHIjRZYQq8PB1MpsNccDIK8WiV+Uw6WzaIXipvaxTEL2yEB0OpEaQv3gs8pkS9Q==} + abitype@1.0.9: + resolution: {integrity: sha512-oN0S++TQmlwWuB+rkA6aiEefLv3SP+2l/tC5mux/TLj6qdA6rF15Vbpex4fHovLsMkwLwTIRj8/Q8vXCS3GfOg==} peerDependencies: typescript: '>=5.0.4' - zod: ^3.22.0 || ^4.0.0 + zod: ^3 >=3.22.0 peerDependenciesMeta: typescript: optional: true @@ -5231,8 +5191,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + ansi-regex@6.2.0: + resolution: {integrity: sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==} engines: {node: '>=12'} ansi-styles@4.3.0: @@ -5243,8 +5203,8 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} any-promise@1.3.0: @@ -5382,8 +5342,8 @@ packages: peerDependencies: axios: 0.x || 1.x - axios@1.12.2: - resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} + axios@1.11.0: + resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -5419,10 +5379,6 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.8.6: - resolution: {integrity: sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==} - hasBin: true - big.js@6.2.2: resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} @@ -5474,8 +5430,8 @@ packages: borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} - bowser@2.12.1: - resolution: {integrity: sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==} + bowser@2.12.0: + resolution: {integrity: sha512-HcOcTudTeEWgbHh0Y1Tyb6fdeR71m4b/QACf0D4KswGTsNeIJQmg38mRENZPAYPZvGFN3fk3604XbQEPdxXdKg==} brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -5490,8 +5446,8 @@ packages: brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - browserslist@4.26.2: - resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==} + browserslist@4.25.3: + resolution: {integrity: sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -5593,23 +5549,23 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001745: - resolution: {integrity: sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==} + caniuse-lite@1.0.30001735: + resolution: {integrity: sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w==} canonicalize@2.1.0: resolution: {integrity: sha512-F705O3xrsUtgt98j7leetNhTWPe+5S72rlL5O4jA1pKqBVQ/dT1O1D6PFxmSXvc0SUOinWS57DKx0I3CHrXJHQ==} hasBin: true - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + chai@5.3.1: + resolution: {integrity: sha512-48af6xm9gQK8rhIcOxWwdGzIervm8BVTin+yRp9HEvU20BtVZ2lBywlIJBzwaDtvo0FvjeL7QdCADoUoqIbV3A==} engines: {node: '>=18'} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.6.2: - resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + chalk@5.6.0: + resolution: {integrity: sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} charenc@0.0.2: @@ -5638,8 +5594,8 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - cipher-base@1.0.7: - resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} + cipher-base@1.0.6: + resolution: {integrity: sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==} engines: {node: '>= 0.10'} classnames@2.5.1: @@ -5705,6 +5661,10 @@ packages: color@3.2.1: resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + colorspace@1.1.4: resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} @@ -5719,8 +5679,8 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} - commander@14.0.1: - resolution: {integrity: sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==} + commander@14.0.0: + resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} engines: {node: '>=20'} commander@2.20.3: @@ -5758,8 +5718,8 @@ packages: engines: {node: ^14.13.0 || >=16.0.0} hasBin: true - concurrently@9.2.1: - resolution: {integrity: sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==} + concurrently@9.2.0: + resolution: {integrity: sha512-IsB/fiXTupmagMW4MNp2lx2cdSN2FfZq78vF90LBB+zZHArbIQZjQtzXCiXnvTxCZSvXanTqFLWBjw2UkLx1SQ==} engines: {node: '>=18'} hasBin: true @@ -5941,8 +5901,8 @@ packages: supports-color: optional: true - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -5950,8 +5910,8 @@ packages: supports-color: optional: true - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -6030,8 +5990,8 @@ packages: detect-browser@5.3.0: resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} - detect-libc@2.1.1: - resolution: {integrity: sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==} + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} detect-node-es@1.1.0: @@ -6137,15 +6097,15 @@ packages: electron-publish@26.0.11: resolution: {integrity: sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A==} - electron-to-chromium@1.5.223: - resolution: {integrity: sha512-qKm55ic6nbEmagFlTFczML33rF90aU+WtrJ9MdTCThrcvDNdUHN4p6QfVN78U06ZmguqXIyMPyYhw2TrbDUwPQ==} + electron-to-chromium@1.5.207: + resolution: {integrity: sha512-mryFrrL/GXDTmAtIVMVf+eIXM09BBPlO5IQ7lUyKmK8d+A4VpRGG+M3ofoVef6qyF8s60rJei8ymlJxjUA8Faw==} electron-winstaller@5.4.0: resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} engines: {node: '>=8.0.0'} - electron@37.5.1: - resolution: {integrity: sha512-RqN3dl6I5yhmynkUc3pUzM6qFCvANau3VGRX9xQEh7FYdwmkqVxKXYM5enrE9LW7j7PzHomQQn6+J2xaF7BHsQ==} + electron@37.3.1: + resolution: {integrity: sha512-7DhktRLqhe6OJh/Bo75bTI0puUYEmIwSzMinocgO63mx3MVjtIn2tYMzLmAleNIlud2htkjpsMG2zT4PiTCloA==} engines: {node: '>= 12.20.55'} hasBin: true @@ -6200,8 +6160,8 @@ packages: err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - error-ex@1.3.4: - resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} es-abstract@1.24.0: resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} @@ -6255,8 +6215,8 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.25.10: - resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} + esbuild@0.25.9: + resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} engines: {node: '>=18'} hasBin: true @@ -6402,8 +6362,8 @@ packages: deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true - eslint@9.36.0: - resolution: {integrity: sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==} + eslint@9.33.0: + resolution: {integrity: sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -6481,9 +6441,9 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - eventsource-parser@3.0.6: - resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} - engines: {node: '>=18.0.0'} + eventsource-parser@3.0.5: + resolution: {integrity: sha512-bSRG85ZrMdmWtm7qkF9He9TNRzc/Bm99gEJMaQoHJ9E6Kv9QBbsldh2oMj7iXmYNEAVvNgvv5vPorG6W+XtBhQ==} + engines: {node: '>=20.0.0'} eventsource@3.0.7: resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} @@ -6564,8 +6524,8 @@ packages: fast-stable-stringify@1.0.0: resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} - fast-uri@3.1.0: - resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} fastestsmallesttextencoderdecoder@1.0.22: resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} @@ -6695,8 +6655,8 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-extra@11.3.2: - resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} + fs-extra@11.3.1: + resolution: {integrity: sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==} engines: {node: '>=14.14'} fs-extra@7.0.1: @@ -6866,9 +6826,9 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hash-base@3.1.2: - resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} - engines: {node: '>= 0.8'} + hash-base@3.1.0: + resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} + engines: {node: '>=4'} hash.js@1.1.7: resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} @@ -6880,8 +6840,8 @@ packages: hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} - hono@4.9.8: - resolution: {integrity: sha512-JW8Bb4RFWD9iOKxg5PbUarBYGM99IcxFl2FPBo2gSJO11jjUDqlP1Bmfyqt8Z/dGhIQ63PMA9LdcLefXyIasyg==} + hono@4.9.2: + resolution: {integrity: sha512-UG2jXGS/gkLH42l/1uROnwXpkjvvxkl3kpopL3LBo27NuaDPI6xHNfuUSilIHcrBkPfl4y0z6y2ByI455TjNRw==} engines: {node: '>=16.9.0'} hosted-git-info@4.1.0: @@ -6946,10 +6906,6 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} - iconv-lite@0.7.0: - resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} - engines: {node: '>=0.10.0'} - idb-keyval@6.2.1: resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} @@ -7015,8 +6971,8 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-arrayish@0.3.4: - resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} is-async-function@2.1.1: resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} @@ -7099,8 +7055,8 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - is-network-error@1.3.0: - resolution: {integrity: sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==} + is-network-error@1.1.0: + resolution: {integrity: sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==} engines: {node: '>=16'} is-number-object@1.1.1: @@ -7179,8 +7135,8 @@ packages: resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} engines: {node: '>= 8.0.0'} - isbinaryfile@5.0.6: - resolution: {integrity: sha512-I+NmIfBHUl+r2wcDd6JwE9yWje/PIVY/R5/CmV8dXLZd5K+L9X2klAOwfAHNnondLXkbHyTAleQAWonpTJBTtw==} + isbinaryfile@5.0.4: + resolution: {integrity: sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==} engines: {node: '>= 18.0.0'} isexe@2.0.0: @@ -7228,8 +7184,8 @@ packages: jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} - jose@6.1.0: - resolution: {integrity: sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==} + jose@6.0.12: + resolution: {integrity: sha512-T8xypXs8CpmiIi78k0E+Lk7T2zlK4zDyg+o1CZ4AkOHgDg98ogdP2BeZ61lTFKFyoEwJ9RgAgN+SdM3iPgNonQ==} joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} @@ -7261,6 +7217,11 @@ packages: canvas: optional: true + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -7323,8 +7284,8 @@ packages: kuler@2.0.0: resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - langsmith@0.3.69: - resolution: {integrity: sha512-YKzu92YAP2o+d+1VmR38xqFX0RIRLKYj1IqdflVEY83X0FoiVlrWO3xDLXgnu7vhZ2N2M6jx8VO9fVF8yy9gHA==} + langsmith@0.3.62: + resolution: {integrity: sha512-ApoGLs28cJCxL91l1PDDkjsA4oLrbeNlE1pyTvyopqXq9bNJrP8JPUNWZm/tpU0DzZpvZFctRzru4gNAr/bkxg==} peerDependencies: '@opentelemetry/api': '*' '@opentelemetry/exporter-trace-otlp-proto': '*' @@ -7357,8 +7318,8 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - libphonenumber-js@1.12.22: - resolution: {integrity: sha512-nzdkDyqlcLV754o1RrOJxh8kycG+63odJVUqnK4dxhw7buNkdTqJc/a/CE0h599dTJgFbzvr6GEOemFBSBryAA==} + libphonenumber-js@1.12.13: + resolution: {integrity: sha512-QZXnR/OGiDcBjF4hGk0wwVrPcZvbSSyzlvkjXv5LFfktj7O2VZDrt4Xs8SgR/vOFco+qk1i8J43ikMXZoTrtPw==} lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} @@ -7395,6 +7356,9 @@ packages: lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -7416,8 +7380,8 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + loupe@3.2.0: + resolution: {integrity: sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==} lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -7443,8 +7407,8 @@ packages: magic-bytes.js@1.12.1: resolution: {integrity: sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==} - magic-string@0.30.19: - resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} make-fetch-happen@10.2.1: resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} @@ -7622,15 +7586,12 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.8.0: - resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + mlly@1.7.4: + resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -7669,8 +7630,8 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} - next@15.5.4: - resolution: {integrity: sha512-xH4Yjhb82sFYQfY3vbkJfgSDgXvBB6a8xPs9i35k6oZJRoQRihZH+4s9Yo2qsWpzBmZ3lPXaJ2KPXLfkvW4LnA==} + next@15.5.0: + resolution: {integrity: sha512-N1lp9Hatw3a9XLt0307lGB4uTKsXDhyOKQo7uYMzX4i0nF/c27grcGXkLdb7VcT8QPYLBa8ouIyEoUQJ2OyeNQ==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -7693,8 +7654,8 @@ packages: no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - node-abi@3.77.0: - resolution: {integrity: sha512-DSmt0OEcLoK4i3NuscSbGjOf3bqiDEutejqENSplMSFA/gmB8mkED9G4pKWnPl7MDU4rSHebKPHeitpDfyH0cQ==} + node-abi@3.75.0: + resolution: {integrity: sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==} engines: {node: '>=10'} node-addon-api@1.7.2: @@ -7738,11 +7699,11 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-mock-http@1.0.3: - resolution: {integrity: sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==} + node-mock-http@1.0.2: + resolution: {integrity: sha512-zWaamgDUdo9SSLw47we78+zYw/bDr5gH8pH7oRRs8V3KmBtu8GLgGIbV2p/gRPd3LWpEOpjQj7X1FOU3VFMJ8g==} - node-releases@2.0.21: - resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} nopt@6.0.0: resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} @@ -7764,8 +7725,8 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nwsapi@2.2.22: - resolution: {integrity: sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==} + nwsapi@2.2.21: + resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} obj-multiplex@1.0.0: resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} @@ -7838,8 +7799,8 @@ packages: zod: optional: true - openai@5.23.0: - resolution: {integrity: sha512-Cfq155NHzI7VWR67LUNJMIgPZy2oSh7Fld/OKhxq648BiUjELAvcge7g30xJ6vAfwwXf6TVK0KKuN+3nmIJG/A==} + openai@5.13.1: + resolution: {integrity: sha512-Jty97Apw40znKSlXZL2YDap1U2eN9NfXbqm/Rj1rExeOLEnhwezpKQ+v43kIqojavUgm30SR3iuvGlNEBR+AFg==} hasBin: true peerDependencies: ws: ^8.18.0 @@ -7850,12 +7811,6 @@ packages: zod: optional: true - openapi-fetch@0.13.8: - resolution: {integrity: sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ==} - - openapi-typescript-helpers@0.0.15: - resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} - opensea-js@7.2.1: resolution: {integrity: sha512-vy7sz2lRMCANrQs9rhNdUsmFSJBjPq1we3/Aib9/sTNudg9830ZvN7XD5if2LBq71L+85tUsxobSNRLBwoEAAg==} engines: {node: '>=20.0.0'} @@ -7904,16 +7859,8 @@ packages: typescript: optional: true - ox@0.9.6: - resolution: {integrity: sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==} - peerDependencies: - typescript: '>=5.4.0' - peerDependenciesMeta: - typescript: - optional: true - - ox@0.9.7: - resolution: {integrity: sha512-KX9Lvv0Rd+SKZXcT6Y85cuYbkmrQbK8Bz26k+s3X4EiT5bSU/hTDNSK/ApBeorJeIaOZbxEmJD2hHW0q1vIDEA==} + ox@0.8.7: + resolution: {integrity: sha512-W1f0FiMf9NZqtHPEDEAEkyzZDwbIKfmH2qmQx8NNiQ/9JhxrSblmtLJsSfTtQG5YKowLOnBlLVguCyxm/7ztxw==} peerDependencies: typescript: '>=5.4.0' peerDependenciesMeta: @@ -8017,8 +7964,9 @@ packages: path-to-regexp@0.1.12: resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -8100,26 +8048,6 @@ packages: resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==} engines: {node: '>=12.0.0'} - porto@0.2.19: - resolution: {integrity: sha512-q1vEJgdtlEOf6byWgD31GHiMwpfLuxFSfx9f7Sw4RGdvpQs2ANBGfnzzardADZegr87ZXsebSp+3vaaznEUzPQ==} - hasBin: true - peerDependencies: - '@tanstack/react-query': '>=5.59.0' - '@wagmi/core': '>=2.16.3' - react: '>=18' - typescript: '>=5.4.0' - viem: '>=2.37.0' - wagmi: '>=2.0.0' - peerDependenciesMeta: - '@tanstack/react-query': - optional: true - react: - optional: true - typescript: - optional: true - wagmi: - optional: true - possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -8130,8 +8058,8 @@ packages: peerDependencies: postcss: ^8.0.0 - postcss-js@4.1.0: - resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + postcss-js@4.0.1: + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 @@ -8195,8 +8123,8 @@ packages: preact@10.24.2: resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} - preact@10.27.2: - resolution: {integrity: sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==} + preact@10.27.1: + resolution: {integrity: sha512-V79raXEWch/rbqoNc7nT9E4ep7lu+mI3+sBmfRD4i1M73R3WLYcCtdI0ibxGVf4eQL8ZIz2nFacqEC+rmnOORQ==} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -8324,9 +8252,9 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - raw-body@3.0.1: - resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} - engines: {node: '>= 0.10'} + raw-body@3.0.0: + resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} + engines: {node: '>= 0.8'} react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} @@ -8431,8 +8359,8 @@ packages: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} - regenerate-unicode-properties@10.2.2: - resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} + regenerate-unicode-properties@10.2.0: + resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} engines: {node: '>=4'} regenerate@1.4.2: @@ -8442,19 +8370,19 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} - regexpu-core@6.4.0: - resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} + regexpu-core@6.2.0: + resolution: {integrity: sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==} engines: {node: '>=4'} regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.13.0: - resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} + regjsparser@0.12.0: + resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} hasBin: true - remeda@2.32.0: - resolution: {integrity: sha512-BZx9DsT4FAgXDTOdgJIc5eY6ECIXMwtlSPQoPglF20ycSWigttDDe88AozEsPPT4OWk5NujroGSBC1phw5uU+w==} + remeda@2.30.0: + resolution: {integrity: sha512-TcRpI1ecqnMer3jHhFtMerGvHFCDlCHljUp0/9A4HxHOh5bSY3kP1l8nQDFMnWYJKl3MSarDNY1tb0Bs/bCmvw==} require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} @@ -8526,16 +8454,15 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - ripemd160@2.0.3: - resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} - engines: {node: '>= 0.8'} + ripemd160@2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} roarr@2.15.4: resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} engines: {node: '>=8.0'} - rollup@4.52.2: - resolution: {integrity: sha512-I25/2QgoROE1vYV+NQ1En9T9UFB9Cmfm2CJ83zZOlaDpvz29wGQSZXWKw7MiNXau7wYgB/T9fVIdIuEQ+KbiiA==} + rollup@4.46.4: + resolution: {integrity: sha512-YbxoxvoqNg9zAmw4+vzh1FkGAiZRK+LhnSrbSrSXMdZYsRPDWoshcSd/pldKRO6lWzv/e9TiJAVQyirYIeSIPQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -8543,8 +8470,8 @@ packages: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} - rpc-websockets@9.2.0: - resolution: {integrity: sha512-DS/XHdPxplQTtNRKiBCRWGBJfjOk56W7fyFUpiYi9fSTWTzoEMbUkn3J4gB0IMniIEVeAGR1/rzFQogzD5MxvQ==} + rpc-websockets@9.1.3: + resolution: {integrity: sha512-I+kNjW0udB4Fetr3vvtRuYZJS0PcSPyyvBcH5sDdoV8DFs5E4W2pTr7aiMlKfPxANTClP9RlqCPolj9dd5MsEA==} rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} @@ -8662,8 +8589,8 @@ packages: engines: {node: '>= 0.10'} hasBin: true - sharp@0.34.4: - resolution: {integrity: sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==} + sharp@0.34.3: + resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@2.0.0: @@ -8704,8 +8631,8 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-swizzle@0.2.4: - resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} simple-update-notifier@2.0.0: resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} @@ -8878,8 +8805,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.2: - resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} strip-bom@3.0.0: @@ -8947,8 +8874,8 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - svix@1.76.1: - resolution: {integrity: sha512-CRuDWBTgYfDnBLRaZdKp9VuoPcNUq9An14c/k+4YJ15Qc5Grvf66vp0jvTltd4t7OIRj+8lM1DAgvSgvf7hdLw==} + svix@1.74.1: + resolution: {integrity: sha512-99J8jSsk0viwkoAENVy/zpVoZxwn3kBdUvvpFaWiKjCkkTcqNZdoBqMmariDFceL4Q41ntWfUYxaWD37IAk9Kg==} symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -8957,15 +8884,9 @@ packages: resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} engines: {node: ^14.18.0 || >=16.0.0} - tabbable@6.2.0: - resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} - tailwind-merge@2.6.0: resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} - tailwind-merge@3.3.1: - resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} - tailwindcss@3.4.17: resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} engines: {node: '>=14.0.0'} @@ -9010,8 +8931,8 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + tinyglobby@0.2.14: + resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} tinypool@1.1.1: @@ -9022,8 +8943,8 @@ packages: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} - tinyspy@4.0.4: - resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + tinyspy@4.0.3: + resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} engines: {node: '>=14.0.0'} tldts-core@6.1.86: @@ -9040,8 +8961,8 @@ packages: resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} engines: {node: '>=14.14'} - to-buffer@1.2.2: - resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + to-buffer@1.2.1: + resolution: {integrity: sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==} engines: {node: '>= 0.4'} to-regex-range@5.0.1: @@ -9162,50 +9083,50 @@ packages: typescript: optional: true - tsx@4.20.5: - resolution: {integrity: sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==} + tsx@4.20.4: + resolution: {integrity: sha512-yyxBKfORQ7LuRt/BQKBXrpcq59ZvSW0XxwfjAt3w2/8PmdxaFzijtMhTawprSHhpzeM5BgU2hXHG3lklIERZXg==} engines: {node: '>=18.0.0'} hasBin: true - turbo-darwin-64@2.5.8: - resolution: {integrity: sha512-Dh5bCACiHO8rUXZLpKw+m3FiHtAp2CkanSyJre+SInEvEr5kIxjGvCK/8MFX8SFRjQuhjtvpIvYYZJB4AGCxNQ==} + turbo-darwin-64@2.5.6: + resolution: {integrity: sha512-3C1xEdo4aFwMJAPvtlPqz1Sw/+cddWIOmsalHFMrsqqydcptwBfu26WW2cDm3u93bUzMbBJ8k3zNKFqxJ9ei2A==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.5.8: - resolution: {integrity: sha512-f1H/tQC9px7+hmXn6Kx/w8Jd/FneIUnvLlcI/7RGHunxfOkKJKvsoiNzySkoHQ8uq1pJnhJ0xNGTlYM48ZaJOQ==} + turbo-darwin-arm64@2.5.6: + resolution: {integrity: sha512-LyiG+rD7JhMfYwLqB6k3LZQtYn8CQQUePbpA8mF/hMLPAekXdJo1g0bUPw8RZLwQXUIU/3BU7tXENvhSGz5DPA==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.5.8: - resolution: {integrity: sha512-hMyvc7w7yadBlZBGl/bnR6O+dJTx3XkTeyTTH4zEjERO6ChEs0SrN8jTFj1lueNXKIHh1SnALmy6VctKMGnWfw==} + turbo-linux-64@2.5.6: + resolution: {integrity: sha512-GOcUTT0xiT/pSnHL4YD6Yr3HreUhU8pUcGqcI2ksIF9b2/r/kRHwGFcsHgpG3+vtZF/kwsP0MV8FTlTObxsYIA==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.5.8: - resolution: {integrity: sha512-LQELGa7bAqV2f+3rTMRPnj5G/OHAe2U+0N9BwsZvfMvHSUbsQ3bBMWdSQaYNicok7wOZcHjz2TkESn1hYK6xIQ==} + turbo-linux-arm64@2.5.6: + resolution: {integrity: sha512-10Tm15bruJEA3m0V7iZcnQBpObGBcOgUcO+sY7/2vk1bweW34LMhkWi8svjV9iDF68+KJDThnYDlYE/bc7/zzQ==} cpu: [arm64] os: [linux] - turbo-windows-64@2.5.8: - resolution: {integrity: sha512-3YdcaW34TrN1AWwqgYL9gUqmZsMT4T7g8Y5Azz+uwwEJW+4sgcJkIi9pYFyU4ZBSjBvkfuPZkGgfStir5BBDJQ==} + turbo-windows-64@2.5.6: + resolution: {integrity: sha512-FyRsVpgaj76It0ludwZsNN40ytHN+17E4PFJyeliBEbxrGTc5BexlXVpufB7XlAaoaZVxbS6KT8RofLfDRyEPg==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.5.8: - resolution: {integrity: sha512-eFC5XzLmgXJfnAK3UMTmVECCwuBcORrWdewoiXBnUm934DY6QN8YowC/srhNnROMpaKaqNeRpoB5FxCww3eteQ==} + turbo-windows-arm64@2.5.6: + resolution: {integrity: sha512-j/tWu8cMeQ7HPpKri6jvKtyXg9K1gRyhdK4tKrrchH8GNHscPX/F71zax58yYtLRWTiK04zNzPcUJuoS0+v/+Q==} cpu: [arm64] os: [win32] - turbo@2.5.8: - resolution: {integrity: sha512-5c9Fdsr9qfpT3hA0EyYSFRZj1dVVsb6KIWubA9JBYZ/9ZEAijgUEae0BBR/Xl/wekt4w65/lYLTFaP3JmwSO8w==} + turbo@2.5.6: + resolution: {integrity: sha512-gxToHmi9oTBNB05UjUsrWf0OyN5ZXtD0apOarC1KIx232Vp3WimRNy3810QzeNSgyD5rsaIDXlxlbnOzlouo+w==} hasBin: true tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} - twitter-api-v2@1.27.0: - resolution: {integrity: sha512-hbIFwzg0NeOcFOdmJqtKMCXjLjc0INff/7NwhnZ2zpnw65oku8i+0eMxo5M0iTc1hs+inD/IpDw3S0Xh2c45QQ==} + twitter-api-v2@1.25.0: + resolution: {integrity: sha512-g3JDd5jwJD+gkEe2Qn3GI5GpasYJjFEauTw70kqiBGu+ectWUgtEKtIaZUGKB50+ApyNhl6v871YCS6un6YEJw==} type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -9281,11 +9202,11 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.12.0: - resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} + undici-types@7.10.0: + resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici-types@7.14.0: + resolution: {integrity: sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==} unicode-canonical-property-names-ecmascript@2.0.1: resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} @@ -9295,12 +9216,12 @@ packages: resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} engines: {node: '>=4'} - unicode-match-property-value-ecmascript@2.2.1: - resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} + unicode-match-property-value-ecmascript@2.2.0: + resolution: {integrity: sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==} engines: {node: '>=4'} - unicode-property-aliases-ecmascript@2.2.0: - resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} + unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} engines: {node: '>=4'} unique-filename@2.0.1: @@ -9326,8 +9247,8 @@ packages: unrs-resolver@1.11.1: resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} - unstorage@1.17.1: - resolution: {integrity: sha512-KKGwRTT0iVBCErKemkJCLs7JdxNVfqTPc/85ae1XES0+bsHbc/sFBfVi5kJp156cc51BHinIH2l3k0EZ24vOBQ==} + unstorage@1.16.1: + resolution: {integrity: sha512-gdpZ3guLDhz+zWIlYP1UwQ259tG5T5vYRzDaHMkQ1bBY1SQPutvZnrRjTFaWUUpseErJIgAZS51h6NOcZVZiqQ==} peerDependencies: '@azure/app-configuration': ^1.8.0 '@azure/cosmos': ^4.2.0 @@ -9341,7 +9262,6 @@ packages: '@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.0.1 aws4fetch: ^1.0.20 db0: '>=0.2.1' @@ -9373,8 +9293,6 @@ packages: optional: true '@vercel/blob': optional: true - '@vercel/functions': - optional: true '@vercel/kv': optional: true aws4fetch: @@ -9435,12 +9353,6 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - usehooks-ts@3.1.1: - resolution: {integrity: sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA==} - engines: {node: '>=16.15.0'} - peerDependencies: - react: ^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc - utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} engines: {node: '>=6.14.2'} @@ -9501,8 +9413,8 @@ packages: typescript: optional: true - viem@2.37.8: - resolution: {integrity: sha512-mL+5yvCQbRIR6QvngDQMfEiZTfNWfd+/QL5yFaOoYbpH3b1Q2ddwF7YG2eI2AcYSh9LE1gtUkbzZLFUAVyj4oQ==} + viem@2.34.0: + resolution: {integrity: sha512-HJZG9Wt0DLX042MG0PK17tpataxtdAEhpta9/Q44FqKwy3xZMI5Lx4jF+zZPuXFuYjZ68R0PXqRwlswHs6r4gA==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -9522,8 +9434,8 @@ packages: vite: optional: true - vite@6.3.6: - resolution: {integrity: sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==} + vite@6.3.5: + resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -9562,8 +9474,8 @@ packages: yaml: optional: true - vite@7.1.7: - resolution: {integrity: sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==} + vite@7.1.3: + resolution: {integrity: sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -9640,8 +9552,8 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - wagmi@2.17.4: - resolution: {integrity: sha512-AJpTQ5O7JFv2LDaRuMiCKxZEVBeDprh9oagA0dLSp/iAEsbd5VwmMy3rn4lCO3pl9umJ+afEkuRIq+5dx02jzg==} + wagmi@2.16.4: + resolution: {integrity: sha512-HthfF/6g7qPnCttl9tLkKoJdWKqMH3Isx4DJ+mkn//Ubom0eKnXH2hr2SMVGTqNQUpsi1knYLUWDGJYkT4hoog==} peerDependencies: '@tanstack/react-query': '>=5.0.0' react: '>=18' @@ -9827,9 +9739,6 @@ packages: x402@0.4.3: resolution: {integrity: sha512-GbIgX2EZYAOZX1ZrEYIVXtjDKLtNuwp7lUlM3dCJAF5TqELP+bDrLy3UsypzNcJoHPVvNa+jB4BPZ83/W2nZDA==} - x402@0.6.1: - resolution: {integrity: sha512-9UmeCSsYzFGav5FdVP70VplKlR3V90P0DZ9fPSrlLVp0ifUVi1S9TztvegkmIHE9xTGZ1GWNi+bkne6N0Ea58w==} - x402@file:../../typescript/packages/x402: resolution: {directory: ../../typescript/packages/x402, type: directory} @@ -9904,9 +9813,6 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - zod@4.1.11: - resolution: {integrity: sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==} - zustand@5.0.0: resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} engines: {node: '>=12.20.0'} @@ -9965,24 +9871,29 @@ snapshots: 7zip-bin@5.2.0: {} - '@across-protocol/app-sdk@0.2.3(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@across-protocol/app-sdk@0.2.3(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@adraffy/ens-normalize@1.10.1': {} - '@adraffy/ens-normalize@1.11.1': {} + '@adraffy/ens-normalize@1.11.0': {} '@alloc/quick-lru@5.2.0': {} '@alloralabs/allora-sdk@0.1.1': dependencies: - '@types/node': 22.18.6 + '@types/node': 22.17.2 typescript: 5.9.2 + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.30 + '@anthropic-ai/sdk@0.39.0(encoding@0.1.13)': dependencies: - '@types/node': 18.19.127 + '@types/node': 18.19.123 '@types/node-fetch': 2.6.13 abort-controller: 3.0.0 agentkeepalive: 4.6.0 @@ -9997,7 +9908,7 @@ snapshots: '@asamuzakjp/css-color@3.2.0': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 lru-cache: 10.4.3 @@ -10005,18 +9916,18 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.893.0 + '@aws-sdk/types': 3.862.0 tslib: 2.8.1 '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.893.0 + '@aws-sdk/types': 3.862.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/types@3.893.0': + '@aws-sdk/types@3.862.0': dependencies: - '@smithy/types': 4.5.0 + '@smithy/types': 4.3.2 tslib: 2.8.1 '@babel/code-frame@7.27.1': @@ -10025,22 +9936,22 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.4': {} + '@babel/compat-data@7.28.0': {} - '@babel/core@7.28.4': + '@babel/core@7.28.3': dependencies: + '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.3 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) - '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.4 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/helpers': 7.28.3 + '@babel/parser': 7.28.3 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - '@jridgewell/remapping': 2.3.5 + '@babel/traverse': 7.28.3 + '@babel/types': 7.28.2 convert-source-map: 2.0.0 - debug: 4.4.3 + debug: 4.4.1 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -10049,50 +9960,50 @@ snapshots: '@babel/generator@7.28.3': dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/parser': 7.28.3 + '@babel/types': 7.28.2 '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/trace-mapping': 0.3.30 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.28.2 '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.28.4 + '@babel/compat-data': 7.28.0 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.26.2 + browserslist: 4.25.3 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.4)': + '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.28.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.4)': + '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-annotate-as-pure': 7.27.3 - regexpu-core: 6.4.0 + regexpu-core: 6.2.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.4)': + '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - debug: 4.4.3 + debug: 4.4.1 lodash.debounce: 4.0.8 resolve: 1.22.10 transitivePeerDependencies: @@ -10102,55 +10013,55 @@ snapshots: '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 + '@babel/traverse': 7.28.3 + '@babel/types': 7.28.2 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 + '@babel/traverse': 7.28.3 + '@babel/types': 7.28.2 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.28.3 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.28.2 '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.4)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-wrap-function': 7.28.3 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.28.3 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.4)': + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.28.3 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 + '@babel/traverse': 7.28.3 + '@babel/types': 7.28.2 transitivePeerDependencies: - supports-color @@ -10163,605 +10074,605 @@ snapshots: '@babel/helper-wrap-function@7.28.3': dependencies: '@babel/template': 7.27.2 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 + '@babel/traverse': 7.28.3 + '@babel/types': 7.28.2 transitivePeerDependencies: - supports-color - '@babel/helpers@7.28.4': + '@babel/helpers@7.28.3': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.4 + '@babel/types': 7.28.2 - '@babel/parser@7.28.4': + '@babel/parser@7.28.3': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.28.2 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.28.3 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.3) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.4)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.28.3 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.4)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 - '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.4)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.4)': + '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.4) - '@babel/traverse': 7.28.4 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.3) + '@babel/traverse': 7.28.3 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.4) + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.3) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-block-scoping@7.28.4(@babel/core@7.28.4)': + '@babel/plugin-transform-block-scoping@7.28.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.4)': + '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.4)': + '@babel/plugin-transform-classes@7.28.3(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-globals': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) - '@babel/traverse': 7.28.4 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) + '@babel/traverse': 7.28.3 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 '@babel/template': 7.27.2 - '@babel/plugin-transform-destructuring@7.28.0(@babel/core@7.28.4)': + '@babel/plugin-transform-destructuring@7.28.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.28.3 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.4)': + '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.28.3 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.28.3 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.4)': + '@babel/plugin-transform-object-rest-spread@7.28.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.4) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.4) - '@babel/traverse': 7.28.4 + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.3) + '@babel/traverse': 7.28.3 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.4)': + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.4)': + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.3) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/types': 7.28.4 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/types': 7.28.2 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.4)': + '@babel/plugin-transform-regenerator@7.28.3(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.4)': + '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.3) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.4)': + '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) '@babel/helper-plugin-utils': 7.27.1 - '@babel/preset-env@7.28.3(@babel/core@7.28.4)': + '@babel/preset-env@7.28.3(@babel/core@7.28.3)': dependencies: - '@babel/compat-data': 7.28.4 - '@babel/core': 7.28.4 + '@babel/compat-data': 7.28.0 + '@babel/core': 7.28.3 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.4) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.4) - '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.4) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.4) - '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-block-scoping': 7.28.4(@babel/core@7.28.4) - '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.4) - '@babel/plugin-transform-classes': 7.28.4(@babel/core@7.28.4) - '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.4) - '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.4) - '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.4) - '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.4) - '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.28.4) - '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.4) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.4) - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.4) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.4) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.4) + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.3) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.3) + '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.3) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-block-scoping': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.3) + '@babel/plugin-transform-classes': 7.28.3(@babel/core@7.28.3) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-object-rest-spread': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.3) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-regenerator': 7.28.3(@babel/core@7.28.3) + '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.3) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.3) + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.3) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.3) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.3) core-js-compat: 3.45.1 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.4)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/types': 7.28.4 + '@babel/types': 7.28.2 esutils: 2.0.3 - '@babel/preset-react@7.27.1(@babel/core@7.28.4)': + '@babel/preset-react@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.4) - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.3) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.27.1(@babel/core@7.28.4)': + '@babel/preset-typescript@7.27.1(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.3) transitivePeerDependencies: - supports-color - '@babel/runtime@7.28.4': {} + '@babel/runtime@7.28.3': {} '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/parser': 7.28.3 + '@babel/types': 7.28.2 - '@babel/traverse@7.28.4': + '@babel/traverse@7.28.3': dependencies: '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.3 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.4 + '@babel/parser': 7.28.3 '@babel/template': 7.27.2 - '@babel/types': 7.28.4 - debug: 4.4.3 + '@babel/types': 7.28.2 + debug: 4.4.1 transitivePeerDependencies: - supports-color - '@babel/types@7.28.4': + '@babel/types@7.28.2': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@base-org/account@1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@base-org/account@1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/hashes': 1.4.0 clsx: 1.2.1 @@ -10769,28 +10680,8 @@ snapshots: idb-keyval: 6.2.1 ox: 0.6.9(typescript@5.9.2)(zod@3.25.76) preact: 10.24.2 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) - transitivePeerDependencies: - - '@types/react' - - bufferutil - - immer - - react - - typescript - - use-sync-external-store - - utf-8-validate - - zod - - '@base-org/account@1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - '@noble/hashes': 1.4.0 - clsx: 1.2.1 - eventemitter3: 5.0.1 - idb-keyval: 6.2.1 - ox: 0.6.9(typescript@5.9.2)(zod@4.1.11) - preact: 10.24.2 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -10801,7 +10692,7 @@ snapshots: - utf-8-validate - zod - '@base-org/account@1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@base-org/account@1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/hashes': 1.4.0 clsx: 1.2.1 @@ -10809,8 +10700,8 @@ snapshots: idb-keyval: 6.2.1 ox: 0.6.9(typescript@5.9.2)(zod@3.25.76) preact: 10.24.2 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -10823,10 +10714,10 @@ snapshots: '@cfworker/json-schema@4.1.1': {} - '@coinbase/agentkit-langchain@0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': + '@coinbase/agentkit-langchain@0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': dependencies: '@coinbase/agentkit': 0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@langchain/core': 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) zod: 3.25.76 transitivePeerDependencies: - '@opentelemetry/api' @@ -10836,12 +10727,12 @@ snapshots: '@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/app-sdk': 0.2.3(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@across-protocol/app-sdk': 0.2.3(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) '@alloralabs/allora-sdk': 0.1.1 '@coinbase/coinbase-sdk': 0.20.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@jup-ag/api': 6.0.44 - '@privy-io/server-auth': 1.32.5(bufferutil@4.0.9)(encoding@0.1.13)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@solana/spl-token': 0.4.14(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@privy-io/server-auth': 1.31.1(bufferutil@4.0.9)(encoding@0.1.13)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) bs58: 4.0.1 canonicalize: 2.1.0 @@ -10850,8 +10741,8 @@ snapshots: md5: 2.3.0 opensea-js: 7.2.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) reflect-metadata: 0.2.2 - twitter-api-v2: 1.27.0 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + twitter-api-v2: 1.25.0 + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -10863,17 +10754,17 @@ snapshots: '@coinbase/cdp-api-client@0.0.18': dependencies: - axios: 1.12.2 + axios: 1.11.0 transitivePeerDependencies: - debug - '@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@coinbase/cdp-api-client': 0.0.18 - jose: 6.1.0 + jose: 6.0.12 ox: 0.8.1(typescript@5.9.2)(zod@3.25.76) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.8(@types/react@19.1.13)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.8(@types/react@19.1.10)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -10885,35 +10776,35 @@ snapshots: - utf-8-validate - zod - '@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1)': + '@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1)': dependencies: - '@coinbase/cdp-core': 0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/cdp-core': 0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) react: 18.3.1 - '@coinbase/cdp-react@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1))(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@coinbase/cdp-react@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(@coinbase/cdp-hooks@0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1))(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@coinbase/cdp-core': 0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/cdp-hooks': 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.13)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-form': 0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@coinbase/cdp-core': 0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/cdp-hooks': 0.0.18(@coinbase/cdp-core@0.0.18(@types/react@19.1.10)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76))(react@18.3.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-form': 0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 transitivePeerDependencies: - '@types/react' - '@types/react-dom' - react-dom - '@coinbase/cdp-sdk@1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@coinbase/cdp-sdk@1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@solana/spl-token': 0.4.14(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) abitype: 1.0.6(typescript@5.9.2)(zod@3.25.76) - axios: 1.12.2 - axios-retry: 4.5.0(axios@1.12.2) - jose: 6.1.0 + axios: 1.11.0 + axios-retry: 4.5.0(axios@1.11.0) + jose: 6.0.12 md5: 2.3.0 uncrypto: 0.1.3 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -10923,17 +10814,17 @@ snapshots: - typescript - utf-8-validate - '@coinbase/cdp-sdk@1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@coinbase/cdp-sdk@1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@solana/spl-token': 0.4.14(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) abitype: 1.0.6(typescript@5.9.2)(zod@3.25.76) - axios: 1.12.2 - axios-retry: 4.5.0(axios@1.12.2) - jose: 6.1.0 + axios: 1.11.0 + axios-retry: 4.5.0(axios@1.11.0) + jose: 6.0.12 md5: 2.3.0 uncrypto: 0.1.3 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -10946,10 +10837,10 @@ snapshots: '@coinbase/coinbase-sdk@0.20.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@scure/bip32': 1.7.0 - abitype: 1.1.1(typescript@5.9.2)(zod@3.25.76) - axios: 1.12.2 - axios-mock-adapter: 1.22.0(axios@1.12.2) - axios-retry: 4.5.0(axios@1.12.2) + abitype: 1.0.9(typescript@5.9.2)(zod@3.25.76) + axios: 1.11.0 + axios-mock-adapter: 1.22.0(axios@1.11.0) + axios-retry: 4.5.0(axios@1.11.0) bip32: 4.0.0 bip39: 3.1.0 decimal.js: 10.6.0 @@ -10958,7 +10849,7 @@ snapshots: ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) jose: 5.10.0 secp256k1: 5.0.1 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - debug @@ -10966,12 +10857,12 @@ snapshots: - utf-8-validate - zod - '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@farcaster/frame-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@tanstack/react-query': 5.90.2(react@19.1.1) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@farcaster/frame-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@tanstack/react-query': 5.85.5(react@19.1.1) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) clsx: 2.1.1 graphql: 16.11.0 graphql-request: 6.1.0(encoding@0.1.13)(graphql@16.11.0) @@ -10979,8 +10870,8 @@ snapshots: react: 19.1.1 react-dom: 19.1.1(react@19.1.1) tailwind-merge: 2.6.0 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -10998,7 +10889,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -11013,70 +10903,48 @@ snapshots: - utf-8-validate - zod - '@coinbase/onchainkit@1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11)': - dependencies: - '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - '@floating-ui/react': 0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@tanstack/react-query': 5.90.2(react@19.1.1) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - clsx: 2.1.1 - graphql: 16.11.0 - graphql-request: 6.1.0(encoding@0.1.13)(graphql@16.11.0) - qrcode: 1.5.4 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - tailwind-merge: 3.3.1 - usehooks-ts: 3.1.1(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) - transitivePeerDependencies: - - '@tanstack/query-core' - - '@types/react' - - '@types/react-dom' - - bufferutil - - encoding - - immer - - typescript - - use-sync-external-store - - utf-8-validate - - zod - - '@coinbase/onchainkit@1.1.0(@tanstack/query-core@5.90.2)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11)': - dependencies: - '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - '@floating-ui/react': 0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@tanstack/react-query': 5.90.2(react@19.1.1) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@farcaster/frame-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@tanstack/react-query': 5.85.5(react@19.1.1) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) clsx: 2.1.1 graphql: 16.11.0 graphql-request: 6.1.0(encoding@0.1.13)(graphql@16.11.0) qrcode: 1.5.4 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - tailwind-merge: 3.3.1 - usehooks-ts: 3.1.1(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) + tailwind-merge: 2.6.0 + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@farcaster/miniapp-sdk' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' - '@tanstack/query-core' - '@types/react' - - '@types/react-dom' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch - bufferutil + - db0 - encoding - immer + - ioredis + - supports-color - typescript + - uploadthing - use-sync-external-store - utf-8-validate - zod @@ -11090,12 +10958,12 @@ snapshots: eth-json-rpc-filters: 6.0.1 eventemitter3: 5.0.1 keccak: 3.0.4 - preact: 10.27.2 + preact: 10.27.1 sha.js: 2.4.12 transitivePeerDependencies: - supports-color - '@coinbase/wallet-sdk@4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/wallet-sdk@4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/hashes': 1.4.0 clsx: 1.2.1 @@ -11103,28 +10971,8 @@ snapshots: idb-keyval: 6.2.1 ox: 0.6.9(typescript@5.9.2)(zod@3.25.76) preact: 10.24.2 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) - transitivePeerDependencies: - - '@types/react' - - bufferutil - - immer - - react - - typescript - - use-sync-external-store - - utf-8-validate - - zod - - '@coinbase/wallet-sdk@4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - '@noble/hashes': 1.4.0 - clsx: 1.2.1 - eventemitter3: 5.0.1 - idb-keyval: 6.2.1 - ox: 0.6.9(typescript@5.9.2)(zod@4.1.11) - preact: 10.24.2 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -11135,7 +10983,7 @@ snapshots: - utf-8-validate - zod - '@coinbase/wallet-sdk@4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/wallet-sdk@4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/hashes': 1.4.0 clsx: 1.2.1 @@ -11143,8 +10991,8 @@ snapshots: idb-keyval: 6.2.1 ox: 0.6.9(typescript@5.9.2)(zod@3.25.76) preact: 10.24.2 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -11157,8 +11005,8 @@ snapshots: '@coinbase/x402@0.3.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@coinbase/cdp-sdk': 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/cdp-sdk': 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: 0.3.7(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: @@ -11169,52 +11017,11 @@ snapshots: - typescript - utf-8-validate - '@coinbase/x402@0.6.4(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)': - dependencies: - '@coinbase/cdp-sdk': 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - x402: 0.6.1(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) - zod: 3.25.76 - 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/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - debug - - encoding - - fastestsmallesttextencoderdecoder - - immer - - ioredis - - react - - supports-color - - typescript - - uploadthing - - utf-8-validate - - ws - '@colors/colors@1.6.0': {} - '@craftamap/esbuild-plugin-html@0.9.0(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@5.0.10)': + '@craftamap/esbuild-plugin-html@0.9.0(bufferutil@4.0.9)(esbuild@0.25.9)(utf-8-validate@5.0.10)': dependencies: - esbuild: 0.25.10 + esbuild: 0.25.9 jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) lodash: 4.17.21 transitivePeerDependencies: @@ -11223,16 +11030,16 @@ snapshots: - supports-color - utf-8-validate - '@csstools/color-helpers@5.1.0': {} + '@csstools/color-helpers@5.0.2': {} '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': dependencies: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + '@csstools/css-color-parser@3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': dependencies: - '@csstools/color-helpers': 5.1.0 + '@csstools/color-helpers': 5.0.2 '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 @@ -11278,7 +11085,7 @@ snapshots: '@electron/get@2.0.3': dependencies: - debug: 4.4.3 + debug: 4.4.1 env-paths: 2.2.1 fs-extra: 8.1.0 got: 11.8.6 @@ -11308,7 +11115,7 @@ snapshots: '@electron/notarize@2.5.0': dependencies: - debug: 4.4.3 + debug: 4.4.1 fs-extra: 9.1.0 promise-retry: 2.0.1 transitivePeerDependencies: @@ -11317,7 +11124,7 @@ snapshots: '@electron/osx-sign@1.3.1': dependencies: compare-version: 0.1.2 - debug: 4.4.3 + debug: 4.4.1 fs-extra: 10.1.0 isbinaryfile: 4.0.10 minimist: 1.2.8 @@ -11330,11 +11137,11 @@ snapshots: '@electron/node-gyp': https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2 '@malept/cross-spawn-promise': 2.0.0 chalk: 4.1.2 - debug: 4.4.3 - detect-libc: 2.1.1 + debug: 4.4.1 + detect-libc: 2.0.4 fs-extra: 10.1.0 got: 11.8.6 - node-abi: 3.77.0 + node-abi: 3.75.0 node-api-version: 0.2.1 ora: 5.4.1 read-binary-file-arch: 1.0.6 @@ -11349,9 +11156,9 @@ snapshots: dependencies: '@electron/asar': 3.2.18 '@malept/cross-spawn-promise': 2.0.0 - debug: 4.4.3 + debug: 4.4.1 dir-compare: 4.2.0 - fs-extra: 11.3.2 + fs-extra: 11.3.1 minimatch: 9.0.5 plist: 3.1.0 transitivePeerDependencies: @@ -11360,26 +11167,26 @@ snapshots: '@electron/windows-sign@1.2.2': dependencies: cross-dirname: 0.1.0 - debug: 4.4.3 - fs-extra: 11.3.2 + debug: 4.4.1 + fs-extra: 11.3.1 minimist: 1.2.8 postject: 1.0.0-alpha.6 transitivePeerDependencies: - supports-color optional: true - '@emnapi/core@1.5.0': + '@emnapi/core@1.4.5': dependencies: - '@emnapi/wasi-threads': 1.1.0 + '@emnapi/wasi-threads': 1.0.4 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.5.0': + '@emnapi/runtime@1.4.5': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.1.0': + '@emnapi/wasi-threads@1.0.4': dependencies: tslib: 2.8.1 optional: true @@ -11387,7 +11194,7 @@ snapshots: '@es-joy/jsdoccomment@0.50.2': dependencies: '@types/estree': 1.0.8 - '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/types': 8.40.0 comment-parser: 1.4.1 esquery: 1.6.0 jsdoc-type-pratt-parser: 4.1.0 @@ -11395,158 +11202,158 @@ snapshots: '@esbuild/aix-ppc64@0.19.12': optional: true - '@esbuild/aix-ppc64@0.25.10': + '@esbuild/aix-ppc64@0.25.9': optional: true '@esbuild/android-arm64@0.19.12': optional: true - '@esbuild/android-arm64@0.25.10': + '@esbuild/android-arm64@0.25.9': optional: true '@esbuild/android-arm@0.19.12': optional: true - '@esbuild/android-arm@0.25.10': + '@esbuild/android-arm@0.25.9': optional: true '@esbuild/android-x64@0.19.12': optional: true - '@esbuild/android-x64@0.25.10': + '@esbuild/android-x64@0.25.9': optional: true '@esbuild/darwin-arm64@0.19.12': optional: true - '@esbuild/darwin-arm64@0.25.10': + '@esbuild/darwin-arm64@0.25.9': optional: true '@esbuild/darwin-x64@0.19.12': optional: true - '@esbuild/darwin-x64@0.25.10': + '@esbuild/darwin-x64@0.25.9': optional: true '@esbuild/freebsd-arm64@0.19.12': optional: true - '@esbuild/freebsd-arm64@0.25.10': + '@esbuild/freebsd-arm64@0.25.9': optional: true '@esbuild/freebsd-x64@0.19.12': optional: true - '@esbuild/freebsd-x64@0.25.10': + '@esbuild/freebsd-x64@0.25.9': optional: true '@esbuild/linux-arm64@0.19.12': optional: true - '@esbuild/linux-arm64@0.25.10': + '@esbuild/linux-arm64@0.25.9': optional: true '@esbuild/linux-arm@0.19.12': optional: true - '@esbuild/linux-arm@0.25.10': + '@esbuild/linux-arm@0.25.9': optional: true '@esbuild/linux-ia32@0.19.12': optional: true - '@esbuild/linux-ia32@0.25.10': + '@esbuild/linux-ia32@0.25.9': optional: true '@esbuild/linux-loong64@0.19.12': optional: true - '@esbuild/linux-loong64@0.25.10': + '@esbuild/linux-loong64@0.25.9': optional: true '@esbuild/linux-mips64el@0.19.12': optional: true - '@esbuild/linux-mips64el@0.25.10': + '@esbuild/linux-mips64el@0.25.9': optional: true '@esbuild/linux-ppc64@0.19.12': optional: true - '@esbuild/linux-ppc64@0.25.10': + '@esbuild/linux-ppc64@0.25.9': optional: true '@esbuild/linux-riscv64@0.19.12': optional: true - '@esbuild/linux-riscv64@0.25.10': + '@esbuild/linux-riscv64@0.25.9': optional: true '@esbuild/linux-s390x@0.19.12': optional: true - '@esbuild/linux-s390x@0.25.10': + '@esbuild/linux-s390x@0.25.9': optional: true '@esbuild/linux-x64@0.19.12': optional: true - '@esbuild/linux-x64@0.25.10': + '@esbuild/linux-x64@0.25.9': optional: true - '@esbuild/netbsd-arm64@0.25.10': + '@esbuild/netbsd-arm64@0.25.9': optional: true '@esbuild/netbsd-x64@0.19.12': optional: true - '@esbuild/netbsd-x64@0.25.10': + '@esbuild/netbsd-x64@0.25.9': optional: true - '@esbuild/openbsd-arm64@0.25.10': + '@esbuild/openbsd-arm64@0.25.9': optional: true '@esbuild/openbsd-x64@0.19.12': optional: true - '@esbuild/openbsd-x64@0.25.10': + '@esbuild/openbsd-x64@0.25.9': optional: true - '@esbuild/openharmony-arm64@0.25.10': + '@esbuild/openharmony-arm64@0.25.9': optional: true '@esbuild/sunos-x64@0.19.12': optional: true - '@esbuild/sunos-x64@0.25.10': + '@esbuild/sunos-x64@0.25.9': optional: true '@esbuild/win32-arm64@0.19.12': optional: true - '@esbuild/win32-arm64@0.25.10': + '@esbuild/win32-arm64@0.25.9': optional: true '@esbuild/win32-ia32@0.19.12': optional: true - '@esbuild/win32-ia32@0.25.10': + '@esbuild/win32-ia32@0.25.9': optional: true '@esbuild/win32-x64@0.19.12': optional: true - '@esbuild/win32-x64@0.25.10': + '@esbuild/win32-x64@0.25.9': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@8.57.1)': + '@eslint-community/eslint-utils@4.7.0(eslint@8.57.1)': dependencies: eslint: 8.57.1 eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.9.0(eslint@9.36.0(jiti@1.21.7))': + '@eslint-community/eslint-utils@4.7.0(eslint@9.33.0(jiti@1.21.7))': dependencies: - eslint: 9.36.0(jiti@1.21.7) + eslint: 9.33.0(jiti@1.21.7) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -11554,7 +11361,7 @@ snapshots: '@eslint/config-array@0.21.0': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.3 + debug: 4.4.1 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -11568,7 +11375,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.4.3 + debug: 4.4.1 espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 @@ -11582,7 +11389,7 @@ snapshots: '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.3 + debug: 4.4.1 espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -11595,7 +11402,7 @@ snapshots: '@eslint/js@8.57.1': {} - '@eslint/js@9.36.0': {} + '@eslint/js@9.33.0': {} '@eslint/object-schema@2.1.6': {} @@ -11635,13 +11442,13 @@ snapshots: - typescript - utf-8-validate - '@farcaster/frame-sdk@0.0.60(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@farcaster/frame-sdk@0.0.60(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@farcaster/frame-core': 0.1.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) '@farcaster/quick-auth': 0.0.5(typescript@5.9.2) comlink: 4.4.2 eventemitter3: 5.0.1 - ox: 0.4.4(typescript@5.9.2)(zod@4.1.11) + ox: 0.4.4(typescript@5.9.2)(zod@3.25.76) transitivePeerDependencies: - bufferutil - encoding @@ -11649,9 +11456,9 @@ snapshots: - utf-8-validate - zod - '@farcaster/frame-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@farcaster/frame-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@farcaster/quick-auth': 0.0.6(typescript@5.9.2) comlink: 4.4.2 eventemitter3: 5.0.1 @@ -11663,7 +11470,7 @@ snapshots: - utf-8-validate - zod - '@farcaster/miniapp-core@0.3.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@farcaster/miniapp-core@0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) ox: 0.4.4(typescript@5.9.2)(zod@3.25.76) @@ -11674,9 +11481,9 @@ snapshots: - typescript - utf-8-validate - '@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@farcaster/miniapp-core': 0.3.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@farcaster/miniapp-core': 0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) '@farcaster/quick-auth': 0.0.6(typescript@5.9.2) comlink: 4.4.2 eventemitter3: 5.0.1 @@ -11688,31 +11495,17 @@ snapshots: - utf-8-validate - zod - '@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - '@farcaster/miniapp-core': 0.3.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@farcaster/quick-auth': 0.0.6(typescript@5.9.2) - comlink: 4.4.2 - eventemitter3: 5.0.1 - ox: 0.4.4(typescript@5.9.2)(zod@4.1.11) - transitivePeerDependencies: - - bufferutil - - encoding - - typescript - - utf-8-validate - - zod - - '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: - '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))': + '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: - '@farcaster/miniapp-sdk': 0.1.10(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@farcaster/quick-auth@0.0.5(typescript@5.9.2)': dependencies: @@ -11730,48 +11523,26 @@ snapshots: dependencies: '@floating-ui/utils': 0.2.10 - '@floating-ui/dom@1.7.4': + '@floating-ui/dom@1.7.3': dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/utils': 0.2.10 - '@floating-ui/react-dom@2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@floating-ui/react-dom@2.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/dom': 1.7.4 + '@floating-ui/dom': 1.7.3 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@floating-ui/react-dom@2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@floating-ui/dom': 1.7.4 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - - '@floating-ui/react@0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@floating-ui/react-dom': 2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@floating-ui/utils': 0.2.10 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - tabbable: 6.2.0 - '@floating-ui/utils@0.2.10': {} '@gar/promisify@1.1.3': {} - '@gemini-wallet/core@0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': - dependencies: - '@metamask/rpc-errors': 7.0.2 - eventemitter3: 5.0.1 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - transitivePeerDependencies: - - supports-color - - '@gemini-wallet/core@0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))': + '@gemini-wallet/core@0.2.0(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: '@metamask/rpc-errors': 7.0.2 eventemitter3: 5.0.1 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - supports-color @@ -11783,9 +11554,9 @@ snapshots: dependencies: react: 19.1.1 - '@hono/node-server@1.19.4(hono@4.9.8)': + '@hono/node-server@1.19.0(hono@4.9.2)': dependencies: - hono: 4.9.8 + hono: 4.9.2 '@hpke/chacha20poly1305@1.7.1': dependencies: @@ -11799,15 +11570,15 @@ snapshots: '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.7': + '@humanfs/node@0.16.6': dependencies: '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.4.3 + '@humanwhocodes/retry': 0.3.1 '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.3 + debug: 4.4.1 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -11816,95 +11587,94 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} - '@humanwhocodes/retry@0.4.3': {} + '@humanwhocodes/retry@0.3.1': {} - '@img/colour@1.0.0': - optional: true + '@humanwhocodes/retry@0.4.3': {} - '@img/sharp-darwin-arm64@0.34.4': + '@img/sharp-darwin-arm64@0.34.3': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.3 + '@img/sharp-libvips-darwin-arm64': 1.2.0 optional: true - '@img/sharp-darwin-x64@0.34.4': + '@img/sharp-darwin-x64@0.34.3': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.3 + '@img/sharp-libvips-darwin-x64': 1.2.0 optional: true - '@img/sharp-libvips-darwin-arm64@1.2.3': + '@img/sharp-libvips-darwin-arm64@1.2.0': optional: true - '@img/sharp-libvips-darwin-x64@1.2.3': + '@img/sharp-libvips-darwin-x64@1.2.0': optional: true - '@img/sharp-libvips-linux-arm64@1.2.3': + '@img/sharp-libvips-linux-arm64@1.2.0': optional: true - '@img/sharp-libvips-linux-arm@1.2.3': + '@img/sharp-libvips-linux-arm@1.2.0': optional: true - '@img/sharp-libvips-linux-ppc64@1.2.3': + '@img/sharp-libvips-linux-ppc64@1.2.0': optional: true - '@img/sharp-libvips-linux-s390x@1.2.3': + '@img/sharp-libvips-linux-s390x@1.2.0': optional: true - '@img/sharp-libvips-linux-x64@1.2.3': + '@img/sharp-libvips-linux-x64@1.2.0': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.2.3': + '@img/sharp-libvips-linuxmusl-arm64@1.2.0': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.2.3': + '@img/sharp-libvips-linuxmusl-x64@1.2.0': optional: true - '@img/sharp-linux-arm64@0.34.4': + '@img/sharp-linux-arm64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.3 + '@img/sharp-libvips-linux-arm64': 1.2.0 optional: true - '@img/sharp-linux-arm@0.34.4': + '@img/sharp-linux-arm@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.3 + '@img/sharp-libvips-linux-arm': 1.2.0 optional: true - '@img/sharp-linux-ppc64@0.34.4': + '@img/sharp-linux-ppc64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.3 + '@img/sharp-libvips-linux-ppc64': 1.2.0 optional: true - '@img/sharp-linux-s390x@0.34.4': + '@img/sharp-linux-s390x@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.3 + '@img/sharp-libvips-linux-s390x': 1.2.0 optional: true - '@img/sharp-linux-x64@0.34.4': + '@img/sharp-linux-x64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.3 + '@img/sharp-libvips-linux-x64': 1.2.0 optional: true - '@img/sharp-linuxmusl-arm64@0.34.4': + '@img/sharp-linuxmusl-arm64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 optional: true - '@img/sharp-linuxmusl-x64@0.34.4': + '@img/sharp-linuxmusl-x64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.3 + '@img/sharp-libvips-linuxmusl-x64': 1.2.0 optional: true - '@img/sharp-wasm32@0.34.4': + '@img/sharp-wasm32@0.34.3': dependencies: - '@emnapi/runtime': 1.5.0 + '@emnapi/runtime': 1.4.5 optional: true - '@img/sharp-win32-arm64@0.34.4': + '@img/sharp-win32-arm64@0.34.3': optional: true - '@img/sharp-win32-ia32@0.34.4': + '@img/sharp-win32-ia32@0.34.3': optional: true - '@img/sharp-win32-x64@0.34.4': + '@img/sharp-win32-x64@0.34.3': optional: true '@isaacs/balanced-match@4.0.1': {} @@ -11917,7 +11687,7 @@ snapshots: dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.2 + strip-ansi: 7.1.0 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 @@ -11925,32 +11695,27 @@ snapshots: '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/trace-mapping': 0.3.30 '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.31': + '@jridgewell/trace-mapping@0.3.30': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 '@jup-ag/api@6.0.44': {} - '@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': + '@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': dependencies: '@cfworker/json-schema': 4.1.1 ansi-styles: 5.2.0 camelcase: 6.3.0 decamelize: 1.2.0 js-tiktoken: 1.0.21 - langsmith: 0.3.69(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + langsmith: 0.3.62(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) mustache: 4.2.0 p-queue: 6.6.2 p-retry: 4.6.2 @@ -11963,27 +11728,27 @@ snapshots: - '@opentelemetry/sdk-trace-base' - openai - '@langchain/langgraph-checkpoint@0.0.18(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': + '@langchain/langgraph-checkpoint@0.0.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': dependencies: - '@langchain/core': 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) uuid: 10.0.0 - '@langchain/langgraph-sdk@0.0.112(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@langchain/langgraph-sdk@0.0.109(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@types/json-schema': 7.0.15 p-queue: 6.6.2 p-retry: 4.6.2 uuid: 9.0.1 optionalDependencies: - '@langchain/core': 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - '@langchain/langgraph@0.2.74(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76))': + '@langchain/langgraph@0.2.74(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76))': dependencies: - '@langchain/core': 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) - '@langchain/langgraph-checkpoint': 0.0.18(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) - '@langchain/langgraph-sdk': 0.0.112(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/langgraph-checkpoint': 0.0.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) + '@langchain/langgraph-sdk': 0.0.109(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) uuid: 10.0.0 zod: 3.25.76 optionalDependencies: @@ -11992,11 +11757,11 @@ snapshots: - react - react-dom - '@langchain/openai@0.5.18(@langchain/core@0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@langchain/openai@0.5.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@langchain/core': 0.3.77(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) js-tiktoken: 1.0.21 - openai: 5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + openai: 5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - ws @@ -12007,12 +11772,12 @@ snapshots: dependencies: '@lit-labs/ssr-dom-shim': 1.4.0 - '@llamaindex/anthropic@0.3.25(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30)': + '@llamaindex/anthropic@0.3.23(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30)': dependencies: '@anthropic-ai/sdk': 0.58.0 '@llamaindex/core': 0.6.5 '@llamaindex/env': 0.1.30 - remeda: 2.32.0 + remeda: 2.30.0 '@llamaindex/cloud@4.0.7(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30)': dependencies: @@ -12023,7 +11788,7 @@ snapshots: '@llamaindex/core@0.6.5': dependencies: '@llamaindex/env': 0.1.30 - '@types/node': 22.18.6 + '@types/node': 22.17.2 magic-bytes.js: 1.12.1 zod: 3.25.76 zod-to-json-schema: 3.24.6(zod@3.25.76) @@ -12067,7 +11832,7 @@ snapshots: '@malept/flatpak-bundler@0.4.0': dependencies: - debug: 4.4.3 + debug: 4.4.1 fs-extra: 9.1.0 lodash: 4.17.21 tmp-promise: 3.0.3 @@ -12114,7 +11879,7 @@ snapshots: '@metamask/onboarding@1.0.1': dependencies: - bowser: 2.12.1 + bowser: 2.12.0 '@metamask/providers@16.1.0': dependencies: @@ -12142,7 +11907,7 @@ snapshots: '@metamask/rpc-errors@7.0.2': dependencies: - '@metamask/utils': 11.8.1 + '@metamask/utils': 11.4.2 fast-safe-stringify: 2.1.1 transitivePeerDependencies: - supports-color @@ -12151,17 +11916,12 @@ snapshots: '@metamask/safe-event-emitter@3.1.2': {} - '@metamask/sdk-analytics@0.0.5': + '@metamask/sdk-communication-layer@0.32.0(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - openapi-fetch: 0.13.8 - - '@metamask/sdk-communication-layer@0.33.1(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@metamask/sdk-analytics': 0.0.5 bufferutil: 4.0.9 cross-fetch: 4.1.0(encoding@0.1.13) date-fns: 2.30.0 - debug: 4.3.4 + debug: 4.4.1 eciesjs: 0.4.15 eventemitter2: 6.4.9 readable-stream: 3.6.2 @@ -12171,22 +11931,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@metamask/sdk-install-modal-web@0.32.1': + '@metamask/sdk-install-modal-web@0.32.0': dependencies: '@paulmillr/qr': 0.2.1 - '@metamask/sdk@0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': + '@metamask/sdk@0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.3 '@metamask/onboarding': 1.0.1 '@metamask/providers': 16.1.0 - '@metamask/sdk-analytics': 0.0.5 - '@metamask/sdk-communication-layer': 0.33.1(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@metamask/sdk-install-modal-web': 0.32.1 + '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metamask/sdk-install-modal-web': 0.32.0 '@paulmillr/qr': 0.2.1 - bowser: 2.12.1 + bowser: 2.12.0 cross-fetch: 4.1.0(encoding@0.1.13) - debug: 4.3.4 + debug: 4.4.1 eciesjs: 0.4.15 eth-rpc-errors: 4.0.3 eventemitter2: 6.4.9 @@ -12205,16 +11964,15 @@ snapshots: '@metamask/superstruct@3.2.1': {} - '@metamask/utils@11.8.1': + '@metamask/utils@11.4.2': dependencies: '@ethereumjs/tx': 4.2.0 '@metamask/superstruct': 3.2.1 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - '@types/lodash': 4.17.20 - debug: 4.4.3 - lodash: 4.17.21 + debug: 4.4.1 + lodash.memoize: 4.1.2 pony-cause: 2.1.11 semver: 7.7.2 uuid: 9.0.1 @@ -12225,7 +11983,7 @@ snapshots: dependencies: '@ethereumjs/tx': 4.2.0 '@types/debug': 4.1.12 - debug: 4.4.3 + debug: 4.4.1 semver: 7.7.2 superstruct: 1.0.4 transitivePeerDependencies: @@ -12238,7 +11996,7 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - debug: 4.3.4 + debug: 4.4.1 pony-cause: 2.1.11 semver: 7.7.2 uuid: 9.0.1 @@ -12252,25 +12010,25 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - debug: 4.3.4 + debug: 4.4.1 pony-cause: 2.1.11 semver: 7.7.2 uuid: 9.0.1 transitivePeerDependencies: - supports-color - '@modelcontextprotocol/sdk@1.18.1': + '@modelcontextprotocol/sdk@1.17.3': dependencies: ajv: 6.12.6 content-type: 1.0.5 cors: 2.8.5 cross-spawn: 7.0.6 eventsource: 3.0.7 - eventsource-parser: 3.0.6 + eventsource-parser: 3.0.5 express: 5.1.0 express-rate-limit: 7.5.1(express@5.1.0) pkce-challenge: 5.0.0 - raw-body: 3.0.1 + raw-body: 3.0.0 zod: 3.25.76 zod-to-json-schema: 3.24.6(zod@3.25.76) transitivePeerDependencies: @@ -12278,12 +12036,12 @@ snapshots: '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@emnapi/core': 1.5.0 - '@emnapi/runtime': 1.5.0 - '@tybys/wasm-util': 0.10.1 + '@emnapi/core': 1.4.5 + '@emnapi/runtime': 1.4.5 + '@tybys/wasm-util': 0.10.0 optional: true - '@next/env@15.5.4': {} + '@next/env@15.5.0': {} '@next/eslint-plugin-next@15.1.7': dependencies: @@ -12293,28 +12051,28 @@ snapshots: dependencies: fast-glob: 3.3.1 - '@next/swc-darwin-arm64@15.5.4': + '@next/swc-darwin-arm64@15.5.0': optional: true - '@next/swc-darwin-x64@15.5.4': + '@next/swc-darwin-x64@15.5.0': optional: true - '@next/swc-linux-arm64-gnu@15.5.4': + '@next/swc-linux-arm64-gnu@15.5.0': optional: true - '@next/swc-linux-arm64-musl@15.5.4': + '@next/swc-linux-arm64-musl@15.5.0': optional: true - '@next/swc-linux-x64-gnu@15.5.4': + '@next/swc-linux-x64-gnu@15.5.0': optional: true - '@next/swc-linux-x64-musl@15.5.4': + '@next/swc-linux-x64-musl@15.5.0': optional: true - '@next/swc-win32-arm64-msvc@15.5.4': + '@next/swc-win32-arm64-msvc@15.5.0': optional: true - '@next/swc-win32-x64-msvc@15.5.4': + '@next/swc-win32-x64-msvc@15.5.0': optional: true '@noble/ciphers@1.2.1': {} @@ -12337,7 +12095,7 @@ snapshots: dependencies: '@noble/hashes': 1.7.1 - '@noble/curves@1.9.1': + '@noble/curves@1.9.6': dependencies: '@noble/hashes': 1.8.0 @@ -12394,29 +12152,29 @@ snapshots: '@pkgr/core@0.2.9': {} - '@privy-io/api-base@1.7.0': + '@privy-io/api-base@1.6.0': dependencies: zod: 3.25.76 - '@privy-io/public-api@2.45.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@privy-io/public-api@2.43.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@privy-io/api-base': 1.7.0 + '@privy-io/api-base': 1.6.0 bs58: 5.0.0 - libphonenumber-js: 1.12.22 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + libphonenumber-js: 1.12.13 + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil - typescript - utf-8-validate - '@privy-io/server-auth@1.32.5(bufferutil@4.0.9)(encoding@0.1.13)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@privy-io/server-auth@1.31.1(bufferutil@4.0.9)(encoding@0.1.13)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: '@hpke/chacha20poly1305': 1.7.1 '@hpke/core': 1.7.4 '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 - '@privy-io/public-api': 2.45.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@privy-io/public-api': 2.43.1(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@scure/base': 1.2.6 '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) canonicalize: 2.1.0 @@ -12424,12 +12182,12 @@ snapshots: jose: 4.15.9 node-fetch-native: 1.6.7 redaxios: 0.5.1 - svix: 1.76.1 + svix: 1.74.1 ts-case-convert: 2.1.0 type-fest: 3.13.1 optionalDependencies: ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - encoding @@ -12442,1096 +12200,770 @@ snapshots: '@radix-ui/primitive@1.1.3': {} - '@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-avatar@1.1.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-avatar@1.1.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.10)(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.13)(react@18.3.1)': + '@radix-ui/react-context-menu@2.2.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.13)(react@19.1.1)': + '@radix-ui/react-context@1.1.2(@types/react@19.1.10)(react@18.3.1)': dependencies: - react: 19.1.1 + react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-context-menu@2.2.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-context@1.1.2(@types/react@19.1.13)(react@18.3.1)': + '@radix-ui/react-direction@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-context@1.1.2(@types/react@19.1.13)(react@19.1.1)': - dependencies: - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - aria-hidden: 1.2.6 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) - aria-hidden: 1.2.6 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-direction@1.1.1(@types/react@19.1.13)(react@18.3.1)': + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.1.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-direction@1.1.1(@types/react@19.1.13)(react@19.1.1)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - react: 19.1.1 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-form@0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-label': 2.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-focus-guards@1.1.3(@types/react@19.1.13)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-focus-guards@1.1.3(@types/react@19.1.13)(react@19.1.1)': - dependencies: - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-form@0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-label': 2.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) '@radix-ui/react-icons@1.3.2(react@18.3.1)': dependencies: react: 18.3.1 - '@radix-ui/react-id@1.1.1(@types/react@19.1.13)(react@18.3.1)': + '@radix-ui/react-id@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-id@1.1.1(@types/react@19.1.13)(react@19.1.1)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-label@2.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-label@2.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-menu@2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-menu@2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-menu@2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-menubar@1.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) - aria-hidden: 1.2.6 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-menubar@1.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-one-time-password-field@0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-one-time-password-field@0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-password-toggle-field@0.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-password-toggle-field@0.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-popover@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@18.3.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-popover@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) - aria-hidden: 1.2.6 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@19.1.1) + react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-popper@1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@floating-ui/react-dom': 2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) '@radix-ui/rect': 1.1.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-popper@1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@floating-ui/react-dom': 2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/rect': 1.1.1 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-presence@1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-presence@1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-progress@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-progress@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-select@2.2.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-select@2.2.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-separator@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-separator@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-slider@1.3.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-slider@1.3.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-slot@1.2.3(@types/react@19.1.13)(react@18.3.1)': + '@radix-ui/react-slot@1.2.3(@types/react@19.1.10)(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-slot@1.2.3(@types/react@19.1.13)(react@19.1.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-switch@1.2.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-switch@1.2.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-toast@1.2.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-toast@1.2.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-toast@1.2.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-toolbar@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-toolbar@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.13)(react@18.3.1)': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.13)(react@19.1.1)': - dependencies: - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.13)(react@18.3.1)': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.10)(react@18.3.1)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.13)(react@19.1.1)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.10)(react@18.3.1)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.13)(react@19.1.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.13)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.13)(react@19.1.1)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.13)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.13)(react@19.1.1)': - dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.1.13)(react@18.3.1)': + '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.1.10)(react@18.3.1)': dependencies: react: 18.3.1 use-sync-external-store: 1.5.0(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.13)(react@18.3.1)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.13)(react@19.1.1)': - dependencies: - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.13)(react@18.3.1)': + '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.13)(react@18.3.1)': + '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: '@radix-ui/rect': 1.1.1 react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.13)(react@19.1.1)': + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: - '@radix-ui/rect': 1.1.1 - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-use-size@1.1.1(@types/react@19.1.13)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 19.1.13 - - '@radix-ui/react-use-size@1.1.1(@types/react@19.1.13)(react@19.1.1)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.1) - react: 19.1.1 - optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) - - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) '@radix-ui/rect@1.1.1': {} - '@radix-ui/themes@3.2.1(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/themes@3.2.1(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/colors': 3.0.0 classnames: 2.5.1 - radix-ui: 1.4.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + radix-ui: 1.4.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll-bar: 2.3.8(@types/react@19.1.13)(react@18.3.1) + react-remove-scroll-bar: 2.3.8(@types/react@19.1.10)(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4)': dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4) transitivePeerDependencies: - bufferutil - typescript @@ -13542,31 +12974,20 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod - - '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - big.js: 6.2.2 - dayjs: 1.11.13 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript - utf-8-validate - zod - '@reown/appkit-controllers@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-controllers@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13582,7 +13003,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13595,48 +13015,13 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-controllers@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@reown/appkit-controllers@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - 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-controllers@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13652,7 +13037,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13669,9 +13053,9 @@ snapshots: dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) valtio: 1.13.2(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13687,7 +13071,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13700,14 +13083,14 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-pay@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-pay@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) lit: 3.3.0 - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13723,7 +13106,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13736,50 +13118,14 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-pay@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@reown/appkit-pay@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) - lit: 3.3.0 - valtio: 1.13.2(@types/react@19.1.13)(react@19.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' - - '@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.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) lit: 3.3.0 - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13795,7 +13141,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13831,7 +13176,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13848,49 +13192,12 @@ snapshots: dependencies: buffer: 6.0.3 - '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76)': + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - 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-scaffold-ui@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) lit: 3.3.0 transitivePeerDependencies: @@ -13908,7 +13215,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13922,12 +13228,12 @@ snapshots: - valtio - zod - '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11)': + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) lit: 3.3.0 transitivePeerDependencies: @@ -13945,7 +13251,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13982,7 +13287,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13996,45 +13300,10 @@ snapshots: - valtio - zod - '@reown/appkit-ui@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-ui@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - 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-ui@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) lit: 3.3.0 qrcode: 1.5.3 @@ -14053,7 +13322,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -14066,10 +13334,10 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-ui@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@reown/appkit-ui@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) lit: 3.3.0 qrcode: 1.5.3 @@ -14088,7 +13356,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -14123,7 +13390,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -14136,92 +13402,16 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-utils@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76)': + '@reown/appkit-utils@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - 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.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - 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.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-polyfills': 1.7.8 '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -14237,7 +13427,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -14250,16 +13439,16 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-utils@1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(react@19.1.1))(zod@3.25.76)': + '@reown/appkit-utils@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-polyfills': 1.7.8 '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 1.13.2(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -14275,45 +13464,28 @@ snapshots: - '@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.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-polyfills': 1.7.8 - '@walletconnect/logger': 2.1.2 - zod: 3.22.4 - transitivePeerDependencies: - - bufferutil + - react - typescript + - uploadthing - utf-8-validate + - zod - '@reown/appkit@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-utils@1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(react@19.1.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-pay': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - bs58: 6.0.0 - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/logger': 2.1.2 + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(react@19.1.1) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -14329,7 +13501,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -14342,21 +13513,32 @@ snapshots: - utf-8-validate - zod - '@reown/appkit@1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@reown/appkit-wallet@1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-polyfills': 1.7.8 + '@walletconnect/logger': 2.1.2 + zod: 3.22.4 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@reown/appkit@1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-pay': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-pay': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) bs58: 6.0.0 - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -14372,7 +13554,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -14385,21 +13566,21 @@ snapshots: - utf-8-validate - zod - '@reown/appkit@1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@reown/appkit@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-pay': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-pay': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1))(zod@4.1.11) + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) bs58: 6.0.0 - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -14415,7 +13596,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -14438,11 +13618,11 @@ snapshots: '@reown/appkit-ui': 1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-utils': 1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(react@19.1.1))(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) bs58: 6.0.0 valtio: 1.13.2(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -14458,7 +13638,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -14473,70 +13652,64 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rollup/rollup-android-arm-eabi@4.52.2': - optional: true - - '@rollup/rollup-android-arm64@4.52.2': - optional: true - - '@rollup/rollup-darwin-arm64@4.52.2': + '@rollup/rollup-android-arm-eabi@4.46.4': optional: true - '@rollup/rollup-darwin-x64@4.52.2': + '@rollup/rollup-android-arm64@4.46.4': optional: true - '@rollup/rollup-freebsd-arm64@4.52.2': + '@rollup/rollup-darwin-arm64@4.46.4': optional: true - '@rollup/rollup-freebsd-x64@4.52.2': + '@rollup/rollup-darwin-x64@4.46.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.52.2': + '@rollup/rollup-freebsd-arm64@4.46.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.52.2': + '@rollup/rollup-freebsd-x64@4.46.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.52.2': + '@rollup/rollup-linux-arm-gnueabihf@4.46.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.52.2': + '@rollup/rollup-linux-arm-musleabihf@4.46.4': optional: true - '@rollup/rollup-linux-loong64-gnu@4.52.2': + '@rollup/rollup-linux-arm64-gnu@4.46.4': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.52.2': + '@rollup/rollup-linux-arm64-musl@4.46.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.52.2': + '@rollup/rollup-linux-loongarch64-gnu@4.46.4': optional: true - '@rollup/rollup-linux-riscv64-musl@4.52.2': + '@rollup/rollup-linux-ppc64-gnu@4.46.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.52.2': + '@rollup/rollup-linux-riscv64-gnu@4.46.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.52.2': + '@rollup/rollup-linux-riscv64-musl@4.46.4': optional: true - '@rollup/rollup-linux-x64-musl@4.52.2': + '@rollup/rollup-linux-s390x-gnu@4.46.4': optional: true - '@rollup/rollup-openharmony-arm64@4.52.2': + '@rollup/rollup-linux-x64-gnu@4.46.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.52.2': + '@rollup/rollup-linux-x64-musl@4.46.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.52.2': + '@rollup/rollup-win32-arm64-msvc@4.46.4': optional: true - '@rollup/rollup-win32-x64-gnu@4.52.2': + '@rollup/rollup-win32-ia32-msvc@4.46.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.52.2': + '@rollup/rollup-win32-x64-msvc@4.46.4': optional: true '@rtsao/scc@1.1.0': {} @@ -14553,30 +13726,10 @@ snapshots: - utf-8-validate - zod - '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - events: 3.3.0 - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod - '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod - - '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript @@ -14603,7 +13756,7 @@ snapshots: '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.6 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 @@ -14633,7 +13786,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/types@4.5.0': + '@smithy/types@4.3.2': dependencies: tslib: 2.8.1 @@ -14795,14 +13948,14 @@ snapshots: '@solana/errors@2.0.0-rc.1(typescript@5.9.2)': dependencies: - chalk: 5.6.2 + chalk: 5.6.0 commander: 12.1.0 typescript: 5.9.2 '@solana/errors@2.3.0(typescript@5.9.2)': dependencies: - chalk: 5.6.2 - commander: 14.0.1 + chalk: 5.6.0 + commander: 14.0.0 typescript: 5.9.2 '@solana/fast-stable-stringify@2.3.0(typescript@5.9.2)': @@ -15066,7 +14219,7 @@ snapshots: '@solana/rpc-spec': 2.3.0(typescript@5.9.2) '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) typescript: 5.9.2 - undici-types: 7.16.0 + undici-types: 7.14.0 '@solana/rpc-types@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': dependencies: @@ -15141,7 +14294,7 @@ snapshots: - fastestsmallesttextencoderdecoder - typescript - '@solana/spl-token@0.4.14(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.4.13(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) @@ -15156,7 +14309,7 @@ snapshots: - typescript - utf-8-validate - '@solana/spl-token@0.4.14(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.4.13(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) @@ -15272,7 +14425,7 @@ snapshots: '@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.3 '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 @@ -15285,7 +14438,7 @@ snapshots: fast-stable-stringify: 1.0.0 jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) node-fetch: 2.7.0(encoding@0.1.13) - rpc-websockets: 9.2.0 + rpc-websockets: 9.1.3 superstruct: 2.0.2 transitivePeerDependencies: - bufferutil @@ -15315,54 +14468,54 @@ snapshots: '@stablelib/wipe@1.0.1': {} - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.4)': + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.4)': + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.4)': + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.4)': + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.4)': + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.4)': + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.4)': + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.4)': + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 - '@svgr/babel-preset@8.1.0(@babel/core@7.28.4)': + '@svgr/babel-preset@8.1.0(@babel/core@7.28.3)': dependencies: - '@babel/core': 7.28.4 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.28.4) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.28.4) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.28.4) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.28.4) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.28.4) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.28.4) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.4) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.28.3) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.28.3) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.28.3) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.28.3) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.28.3) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.28.3) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.3) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.3) '@svgr/core@8.1.0(typescript@5.9.2)': dependencies: - '@babel/core': 7.28.4 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@svgr/babel-preset': 8.1.0(@babel/core@7.28.3) camelcase: 6.3.0 cosmiconfig: 8.3.6(typescript@5.9.2) snake-case: 3.0.4 @@ -15372,13 +14525,13 @@ snapshots: '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.28.2 entities: 4.5.0 '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.2))': dependencies: - '@babel/core': 7.28.4 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@svgr/babel-preset': 8.1.0(@babel/core@7.28.3) '@svgr/core': 8.1.0(typescript@5.9.2) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 @@ -15396,11 +14549,11 @@ snapshots: '@svgr/webpack@8.1.0(typescript@5.9.2)': dependencies: - '@babel/core': 7.28.4 - '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.4) - '@babel/preset-env': 7.28.3(@babel/core@7.28.4) - '@babel/preset-react': 7.27.1(@babel/core@7.28.4) - '@babel/preset-typescript': 7.27.1(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.3) + '@babel/preset-env': 7.28.3(@babel/core@7.28.3) + '@babel/preset-react': 7.27.1(@babel/core@7.28.3) + '@babel/preset-typescript': 7.27.1(@babel/core@7.28.3) '@svgr/core': 8.1.0(typescript@5.9.2) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2)) '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2))(typescript@5.9.2) @@ -15420,53 +14573,53 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tanstack/query-core@5.90.2': {} + '@tanstack/query-core@5.85.5': {} - '@tanstack/react-query@5.90.2(react@19.1.1)': + '@tanstack/react-query@5.85.5(react@19.1.1)': dependencies: - '@tanstack/query-core': 5.90.2 + '@tanstack/query-core': 5.85.5 react: 19.1.1 '@tootallnate/once@2.0.0': {} '@trysound/sax@0.2.0': {} - '@tybys/wasm-util@0.10.1': + '@tybys/wasm-util@0.10.0': dependencies: tslib: 2.8.1 optional: true '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/parser': 7.28.3 + '@babel/types': 7.28.2 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.28.2 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/parser': 7.28.3 + '@babel/types': 7.28.2 '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.28.2 '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.18.6 + '@types/node': 22.17.2 '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 22.18.6 + '@types/node': 22.17.2 '@types/responselike': 1.0.3 '@types/chai@5.2.2': @@ -15475,7 +14628,7 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 22.18.6 + '@types/node': 22.17.2 '@types/debug@4.1.12': dependencies: @@ -15487,7 +14640,7 @@ snapshots: '@types/express-serve-static-core@5.0.7': dependencies: - '@types/node': 22.18.6 + '@types/node': 22.17.2 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 0.17.5 @@ -15500,7 +14653,7 @@ snapshots: '@types/fs-extra@9.0.13': dependencies: - '@types/node': 22.18.6 + '@types/node': 22.17.2 '@types/http-cache-semantics@4.0.4': {} @@ -15512,7 +14665,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 22.18.6 + '@types/node': 22.17.2 '@types/lodash@4.17.20': {} @@ -15522,20 +14675,20 @@ snapshots: '@types/node-fetch@2.6.13': dependencies: - '@types/node': 20.19.17 + '@types/node': 20.19.11 form-data: 4.0.4 '@types/node@12.20.55': {} - '@types/node@18.19.127': + '@types/node@18.19.123': dependencies: undici-types: 5.26.5 - '@types/node@20.19.17': + '@types/node@20.19.11': dependencies: undici-types: 6.21.0 - '@types/node@22.18.6': + '@types/node@22.17.2': dependencies: undici-types: 6.21.0 @@ -15543,13 +14696,13 @@ snapshots: dependencies: undici-types: 6.19.8 - '@types/node@24.5.2': + '@types/node@24.3.0': dependencies: - undici-types: 7.12.0 + undici-types: 7.10.0 '@types/plist@3.0.5': dependencies: - '@types/node': 22.18.6 + '@types/node': 22.17.2 xmlbuilder: 15.1.1 optional: true @@ -15557,17 +14710,17 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react-dom@19.1.9(@types/react@19.1.13)': + '@types/react-dom@19.1.7(@types/react@19.1.10)': dependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - '@types/react@19.1.13': + '@types/react@19.1.10': dependencies: csstype: 3.1.3 '@types/responselike@1.0.3': dependencies: - '@types/node': 22.18.6 + '@types/node': 22.17.2 '@types/retry@0.12.0': {} @@ -15576,12 +14729,12 @@ snapshots: '@types/send@0.17.5': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.18.6 + '@types/node': 22.17.2 '@types/serve-static@1.15.8': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.18.6 + '@types/node': 22.17.2 '@types/send': 0.17.5 '@types/triple-beam@1.3.5': {} @@ -15597,25 +14750,25 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 22.18.6 + '@types/node': 22.17.2 '@types/ws@8.18.1': dependencies: - '@types/node': 22.18.6 + '@types/node': 22.17.2 '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.18.6 + '@types/node': 22.17.2 optional: true - '@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.44.1(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/type-utils': 8.44.1(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.1(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.1 + '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.40.0 + '@typescript-eslint/type-utils': 8.40.0(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/utils': 8.40.0(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.40.0 eslint: 8.57.1 graphemer: 1.4.0 ignore: 7.0.5 @@ -15625,15 +14778,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/type-utils': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.1 - eslint: 9.36.0(jiti@1.21.7) + '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.40.0 + '@typescript-eslint/type-utils': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/utils': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.40.0 + eslint: 9.33.0(jiti@1.21.7) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -15642,81 +14795,81 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2)': + '@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2)': dependencies: - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.1 - debug: 4.4.3 + '@typescript-eslint/scope-manager': 8.40.0 + '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.40.0 + debug: 4.4.1 eslint: 8.57.1 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2)': dependencies: - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.1 - debug: 4.4.3 - eslint: 9.36.0(jiti@1.21.7) + '@typescript-eslint/scope-manager': 8.40.0 + '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.40.0 + debug: 4.4.1 + eslint: 9.33.0(jiti@1.21.7) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.44.1(typescript@5.9.2)': + '@typescript-eslint/project-service@8.40.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) - '@typescript-eslint/types': 8.44.1 - debug: 4.4.3 + '@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.9.2) + '@typescript-eslint/types': 8.40.0 + debug: 4.4.1 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.44.1': + '@typescript-eslint/scope-manager@8.40.0': dependencies: - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/visitor-keys': 8.44.1 + '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/visitor-keys': 8.40.0 - '@typescript-eslint/tsconfig-utils@8.44.1(typescript@5.9.2)': + '@typescript-eslint/tsconfig-utils@8.40.0(typescript@5.9.2)': dependencies: typescript: 5.9.2 - '@typescript-eslint/type-utils@8.44.1(eslint@8.57.1)(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.40.0(eslint@8.57.1)(typescript@5.9.2)': dependencies: - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.1(eslint@8.57.1)(typescript@5.9.2) - debug: 4.4.3 + '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.40.0(eslint@8.57.1)(typescript@5.9.2) + debug: 4.4.1 eslint: 8.57.1 ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2)': dependencies: - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) - debug: 4.4.3 - eslint: 9.36.0(jiti@1.21.7) + '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + debug: 4.4.1 + eslint: 9.33.0(jiti@1.21.7) ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.44.1': {} + '@typescript-eslint/types@8.40.0': {} - '@typescript-eslint/typescript-estree@8.44.1(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.40.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/project-service': 8.44.1(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/visitor-keys': 8.44.1 - debug: 4.4.3 + '@typescript-eslint/project-service': 8.40.0(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.9.2) + '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/visitor-keys': 8.40.0 + debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -15726,31 +14879,31 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.44.1(eslint@8.57.1)(typescript@5.9.2)': + '@typescript-eslint/utils@8.40.0(eslint@8.57.1)(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) + '@typescript-eslint/scope-manager': 8.40.0 + '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) eslint: 8.57.1 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0(jiti@1.21.7)) - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - eslint: 9.36.0(jiti@1.21.7) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.40.0 + '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) + eslint: 9.33.0(jiti@1.21.7) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.44.1': + '@typescript-eslint/visitor-keys@8.40.0': dependencies: - '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/types': 8.40.0 eslint-visitor-keys: 4.2.1 '@ungap/structured-clone@1.3.0': {} @@ -15814,19 +14967,19 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@upstash/redis@1.35.4': + '@upstash/redis@1.35.3': dependencies: uncrypto: 0.1.3 - '@vitejs/plugin-react@4.7.0(vite@7.1.7(@types/node@24.5.2)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1))': + '@vitejs/plugin-react@4.7.0(vite@7.1.3(@types/node@24.3.0)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1))': dependencies: - '@babel/core': 7.28.4 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.3) '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 7.1.7(@types/node@24.5.2)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite: 7.1.3(@types/node@24.3.0)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -15835,16 +14988,16 @@ snapshots: '@types/chai': 5.2.2 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.3.3 + chai: 5.3.1 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.19 + magic-string: 0.30.17 optionalDependencies: - vite: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -15859,32 +15012,31 @@ snapshots: '@vitest/snapshot@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.19 + magic-string: 0.30.17 pathe: 2.0.3 '@vitest/spy@3.2.4': dependencies: - tinyspy: 4.0.4 + tinyspy: 4.0.3 '@vitest/utils@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - loupe: 3.2.1 + loupe: 3.2.0 tinyrainbow: 2.0.0 - '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)': + '@wagmi/connectors@5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@base-org/account': 1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.2.0(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -15899,11 +15051,9 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' - - '@tanstack/react-query' - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15916,22 +15066,20 @@ snapshots: - uploadthing - use-sync-external-store - utf-8-validate - - wagmi - zod - '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)': + '@wagmi/connectors@5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@base-org/account': 1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.2.0(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -15946,11 +15094,9 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' - - '@tanstack/react-query' - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -15963,116 +15109,20 @@ snapshots: - uploadthing - use-sync-external-store - utf-8-validate - - wagmi - zod - '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@3.25.76)': + '@wagmi/connectors@5.9.4(@types/react@19.1.10)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@base-org/account': 1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.2.0(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11)) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - optionalDependencies: - typescript: 5.9.2 - 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' - - '@tanstack/react-query' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - immer - - ioredis - - react - - supports-color - - uploadthing - - use-sync-external-store - - utf-8-validate - - wagmi - - zod - - '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11)': - dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11) - '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11)) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - optionalDependencies: - typescript: 5.9.2 - 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' - - '@tanstack/react-query' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - immer - - ioredis - - react - - supports-color - - uploadthing - - use-sync-external-store - - utf-8-validate - - wagmi - - zod - - '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11)': - dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.11) - '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11)) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -16087,11 +15137,9 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' - - '@tanstack/react-query' - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -16104,22 +15152,20 @@ snapshots: - uploadthing - use-sync-external-store - utf-8-validate - - wagmi - zod - '@wagmi/connectors@5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@wagmi/core@2.21.1(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76))(zod@3.25.76)': + '@wagmi/connectors@5.9.4(@wagmi/core@2.19.0(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@gemini-wallet/core': 0.2.0(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@base-org/account': 1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.2.0(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) '@walletconnect/ethereum-provider': 2.21.1(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - porto: 0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@wagmi/core@2.21.1(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76)) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -16134,11 +15180,9 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' - - '@tanstack/react-query' - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -16151,47 +15195,16 @@ snapshots: - uploadthing - use-sync-external-store - utf-8-validate - - wagmi - zod - '@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': - dependencies: - eventemitter3: 5.0.1 - mipd: 0.0.7(typescript@5.9.2) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) - optionalDependencies: - '@tanstack/query-core': 5.90.2 - typescript: 5.9.2 - transitivePeerDependencies: - - '@types/react' - - immer - - react - - use-sync-external-store - - '@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))': - dependencies: - eventemitter3: 5.0.1 - mipd: 0.0.7(typescript@5.9.2) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - zustand: 5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) - optionalDependencies: - '@tanstack/query-core': 5.90.2 - typescript: 5.9.2 - transitivePeerDependencies: - - '@types/react' - - immer - - react - - use-sync-external-store - - '@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.9.2) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zustand: 5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.0(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) optionalDependencies: - '@tanstack/query-core': 5.90.2 + '@tanstack/query-core': 5.85.5 typescript: 5.9.2 transitivePeerDependencies: - '@types/react' @@ -16199,14 +15212,14 @@ snapshots: - react - use-sync-external-store - '@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))': + '@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.9.2) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - zustand: 5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.0(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) optionalDependencies: - '@tanstack/query-core': 5.90.2 + '@tanstack/query-core': 5.85.5 typescript: 5.9.2 transitivePeerDependencies: - '@types/react' @@ -16214,153 +15227,21 @@ snapshots: - react - use-sync-external-store - '@walletconnect/core@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - 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.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) - '@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.0(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/window-getters': 1.0.1 - es-toolkit: 1.33.0 - events: 3.3.0 - uint8arrays: 3.1.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/core@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': - 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.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) - '@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.0(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@walletconnect/window-getters': 1.0.1 - es-toolkit: 1.33.0 - events: 3.3.0 - uint8arrays: 3.1.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/core@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - 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.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) - '@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.1(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/window-getters': 1.0.1 - es-toolkit: 1.33.0 - events: 3.3.0 - uint8arrays: 3.1.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/core@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/core@2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': 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.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) '@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.1(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 @@ -16379,7 +15260,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -16390,23 +15270,25 @@ snapshots: - utf-8-validate - zod - '@walletconnect/environment@1.0.1': - dependencies: - tslib: 1.14.1 - - '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/core@2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@reown/appkit': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) + '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) - '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@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.1(@upstash/redis@1.35.3) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 events: 3.3.0 + uint8arrays: 3.1.0 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -16419,34 +15301,34 @@ snapshots: - '@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/ethereum-provider@2.21.1(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/environment@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@reown/appkit': 1.7.8(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit': 1.7.8(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) - '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) + '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -16463,7 +15345,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -16476,18 +15357,18 @@ snapshots: - utf-8-validate - zod - '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@reown/appkit': 1.7.8(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@reown/appkit': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) - '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) + '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -16504,7 +15385,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -16524,11 +15404,11 @@ snapshots: '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) - '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) + '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -16545,7 +15425,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -16605,11 +15484,11 @@ snapshots: - bufferutil - utf-8-validate - '@walletconnect/keyvaluestorage@1.1.1(@upstash/redis@1.35.4)': + '@walletconnect/keyvaluestorage@1.1.1(@upstash/redis@1.35.3)': dependencies: '@walletconnect/safe-json': 1.0.2 idb-keyval: 6.2.2 - unstorage: 1.17.1(@upstash/redis@1.35.4)(idb-keyval@6.2.2) + unstorage: 1.16.1(@upstash/redis@1.35.3)(idb-keyval@6.2.2) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -16623,7 +15502,6 @@ snapshots: - '@planetscale/database' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 @@ -16651,88 +15529,16 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/sign-client@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - dependencies: - '@walletconnect/core': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@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.0(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - 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.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - '@walletconnect/core': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@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.0(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - 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.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/sign-client@2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@walletconnect/core': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/core': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@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.1(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -16748,7 +15554,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -16759,16 +15564,16 @@ snapshots: - utf-8-validate - zod - '@walletconnect/sign-client@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/sign-client@2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@walletconnect/core': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/core': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@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.1(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -16784,7 +15589,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -16799,12 +15603,12 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/types@2.21.0(@upstash/redis@1.35.4)': + '@walletconnect/types@2.21.0(@upstash/redis@1.35.3)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) '@walletconnect/logger': 2.1.2 events: 3.3.0 transitivePeerDependencies: @@ -16821,19 +15625,18 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 - ioredis - uploadthing - '@walletconnect/types@2.21.1(@upstash/redis@1.35.4)': + '@walletconnect/types@2.21.1(@upstash/redis@1.35.3)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) '@walletconnect/logger': 2.1.2 events: 3.3.0 transitivePeerDependencies: @@ -16850,25 +15653,24 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 - ioredis - uploadthing - '@walletconnect/universal-provider@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/universal-provider@2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/sign-client': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -16885,7 +15687,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -16897,18 +15698,18 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/universal-provider@2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/sign-client': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -16925,7 +15726,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -16937,18 +15737,18 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/universal-provider@2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -16965,7 +15765,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -16977,18 +15776,18 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': + '@walletconnect/universal-provider@2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.4) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -17005,7 +15804,6 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -17017,18 +15815,18 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/utils@2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) '@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.0(@upstash/redis@1.35.4) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) '@walletconnect/window-getters': 1.0.1 '@walletconnect/window-metadata': 1.0.1 bs58: 6.0.0 @@ -17050,51 +15848,6 @@ snapshots: - '@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.21.0(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - '@noble/ciphers': 1.2.1 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) - '@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.0(@upstash/redis@1.35.4) - '@walletconnect/window-getters': 1.0.1 - '@walletconnect/window-metadata': 1.0.1 - bs58: 6.0.0 - detect-browser: 5.3.0 - query-string: 7.1.3 - uint8arrays: 3.1.0 - viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - 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 @@ -17105,18 +15858,18 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@walletconnect/utils@2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) '@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.1(@upstash/redis@1.35.4) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) '@walletconnect/window-getters': 1.0.1 '@walletconnect/window-metadata': 1.0.1 bs58: 6.0.0 @@ -17138,51 +15891,6 @@ snapshots: - '@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.21.1(@upstash/redis@1.35.4)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)': - dependencies: - '@noble/ciphers': 1.2.1 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.4) - '@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.1(@upstash/redis@1.35.4) - '@walletconnect/window-getters': 1.0.1 - '@walletconnect/window-metadata': 1.0.1 - bs58: 6.0.0 - detect-browser: 5.3.0 - query-string: 7.1.3 - uint8arrays: 3.1.0 - viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - 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 @@ -17211,41 +15919,21 @@ snapshots: typescript: 5.9.2 zod: 3.25.76 - abitype@1.0.8(typescript@5.9.2)(zod@3.25.76): - optionalDependencies: - typescript: 5.9.2 - zod: 3.25.76 - - abitype@1.0.8(typescript@5.9.2)(zod@4.1.11): - optionalDependencies: - typescript: 5.9.2 - zod: 4.1.11 - - abitype@1.1.0(typescript@5.9.2)(zod@3.22.4): + abitype@1.0.8(typescript@5.9.2)(zod@3.22.4): optionalDependencies: typescript: 5.9.2 zod: 3.22.4 - abitype@1.1.0(typescript@5.9.2)(zod@3.25.76): + abitype@1.0.8(typescript@5.9.2)(zod@3.25.76): optionalDependencies: typescript: 5.9.2 zod: 3.25.76 - abitype@1.1.0(typescript@5.9.2)(zod@4.1.11): - optionalDependencies: - typescript: 5.9.2 - zod: 4.1.11 - - abitype@1.1.1(typescript@5.9.2)(zod@3.25.76): + abitype@1.0.9(typescript@5.9.2)(zod@3.25.76): optionalDependencies: typescript: 5.9.2 zod: 3.25.76 - abitype@1.1.1(typescript@5.9.2)(zod@4.1.11): - optionalDependencies: - typescript: 5.9.2 - zod: 4.1.11 - abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -17270,7 +15958,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -17299,13 +15987,13 @@ snapshots: ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 + fast-uri: 3.0.6 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 ansi-regex@5.0.1: {} - ansi-regex@6.2.2: {} + ansi-regex@6.2.0: {} ansi-styles@4.3.0: dependencies: @@ -17313,7 +16001,7 @@ snapshots: ansi-styles@5.2.0: {} - ansi-styles@6.2.3: {} + ansi-styles@6.2.1: {} any-promise@1.3.0: {} @@ -17342,7 +16030,7 @@ snapshots: builder-util-runtime: 9.3.1 chromium-pickle-js: 0.2.0 config-file-ts: 0.2.8-rc1 - debug: 4.4.3 + debug: 4.4.1 dmg-builder: 26.0.12(electron-builder-squirrel-windows@26.0.12) dotenv: 16.6.1 dotenv-expand: 11.0.7 @@ -17352,7 +16040,7 @@ snapshots: fs-extra: 10.1.0 hosted-git-info: 4.1.0 is-ci: 3.0.1 - isbinaryfile: 5.0.6 + isbinaryfile: 5.0.4 js-yaml: 4.1.0 json5: 2.2.3 lazy-val: 1.0.5 @@ -17482,18 +16170,18 @@ snapshots: axe-core@4.10.3: {} - axios-mock-adapter@1.22.0(axios@1.12.2): + axios-mock-adapter@1.22.0(axios@1.11.0): dependencies: - axios: 1.12.2 + axios: 1.11.0 fast-deep-equal: 3.1.3 is-buffer: 2.0.5 - axios-retry@4.5.0(axios@1.12.2): + axios-retry@4.5.0(axios@1.11.0): dependencies: - axios: 1.12.2 + axios: 1.11.0 is-retry-allowed: 2.2.0 - axios@1.12.2: + axios@1.11.0: dependencies: follow-redirects: 1.15.11 form-data: 4.0.4 @@ -17503,27 +16191,27 @@ snapshots: axobject-query@4.1.0: {} - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.4): + babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.3): dependencies: - '@babel/compat-data': 7.28.4 - '@babel/core': 7.28.4 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) + '@babel/compat-data': 7.28.0 + '@babel/core': 7.28.3 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.4): + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.3): dependencies: - '@babel/core': 7.28.4 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) core-js-compat: 3.45.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.4): + babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.3): dependencies: - '@babel/core': 7.28.4 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) + '@babel/core': 7.28.3 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) transitivePeerDependencies: - supports-color @@ -17539,8 +16227,6 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.8.6: {} - big.js@6.2.2: {} bigint-buffer@1.1.5: @@ -17597,12 +16283,12 @@ snapshots: dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 4.4.3 + debug: 4.4.1 http-errors: 2.0.0 iconv-lite: 0.6.3 on-finished: 2.4.1 qs: 6.14.0 - raw-body: 3.0.1 + raw-body: 3.0.0 type-is: 2.0.1 transitivePeerDependencies: - supports-color @@ -17618,7 +16304,7 @@ snapshots: bs58: 4.0.1 text-encoding-utf-8: 1.0.2 - bowser@2.12.1: {} + bowser@2.12.0: {} brace-expansion@1.1.12: dependencies: @@ -17635,13 +16321,12 @@ snapshots: brorand@1.1.0: {} - browserslist@4.26.2: + browserslist@4.25.3: dependencies: - baseline-browser-mapping: 2.8.6 - caniuse-lite: 1.0.30001745 - electron-to-chromium: 1.5.223 - node-releases: 2.0.21 - update-browserslist-db: 1.1.3(browserslist@4.26.2) + caniuse-lite: 1.0.30001735 + electron-to-chromium: 1.5.207 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.25.3) bs58@4.0.1: dependencies: @@ -17683,7 +16368,7 @@ snapshots: builder-util-runtime@9.3.1: dependencies: - debug: 4.4.3 + debug: 4.4.1 sax: 1.4.1 transitivePeerDependencies: - supports-color @@ -17696,7 +16381,7 @@ snapshots: builder-util-runtime: 9.3.1 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.1 fs-extra: 10.1.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 @@ -17715,9 +16400,9 @@ snapshots: esbuild: 0.19.12 load-tsconfig: 0.2.5 - bundle-require@5.1.0(esbuild@0.25.10): + bundle-require@5.1.0(esbuild@0.25.9): dependencies: - esbuild: 0.25.10 + esbuild: 0.25.9 load-tsconfig: 0.2.5 bytes@3.1.2: {} @@ -17784,16 +16469,16 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001745: {} + caniuse-lite@1.0.30001735: {} canonicalize@2.1.0: {} - chai@5.3.3: + chai@5.3.1: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.2.1 + loupe: 3.2.0 pathval: 2.0.1 chalk@4.1.2: @@ -17801,7 +16486,7 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.6.2: {} + chalk@5.6.0: {} charenc@0.0.2: {} @@ -17829,11 +16514,10 @@ snapshots: ci-info@3.9.0: {} - cipher-base@1.0.7: + cipher-base@1.0.6: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 - to-buffer: 1.2.2 classnames@2.5.1: {} @@ -17890,13 +16574,19 @@ snapshots: color-string@1.9.1: dependencies: color-name: 1.1.4 - simple-swizzle: 0.2.4 + simple-swizzle: 0.2.2 color@3.2.1: dependencies: color-convert: 1.9.3 color-string: 1.9.1 + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + colorspace@1.1.4: dependencies: color: 3.2.1 @@ -17910,7 +16600,7 @@ snapshots: commander@12.1.0: {} - commander@14.0.1: {} + commander@14.0.0: {} commander@2.20.3: {} @@ -17941,9 +16631,10 @@ snapshots: tree-kill: 1.2.2 yargs: 17.7.2 - concurrently@9.2.1: + concurrently@9.2.0: dependencies: chalk: 4.1.2 + lodash: 4.17.21 rxjs: 7.8.2 shell-quote: 1.8.3 supports-color: 8.1.1 @@ -17987,7 +16678,7 @@ snapshots: core-js-compat@3.45.1: dependencies: - browserslist: 4.26.2 + browserslist: 4.25.3 core-util-is@1.0.2: optional: true @@ -18017,10 +16708,10 @@ snapshots: create-hash@1.2.0: dependencies: - cipher-base: 1.0.7 + cipher-base: 1.0.6 inherits: 2.0.4 md5.js: 1.3.5 - ripemd160: 2.0.3 + ripemd160: 2.0.2 sha.js: 2.4.12 cross-dirname@0.1.0: @@ -18114,7 +16805,7 @@ snapshots: date-fns@2.30.0: dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.3 dayjs@1.11.13: {} @@ -18126,11 +16817,11 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.3.4: + debug@4.3.7: dependencies: - ms: 2.1.2 + ms: 2.1.3 - debug@4.4.3: + debug@4.4.1: dependencies: ms: 2.1.3 @@ -18176,9 +16867,9 @@ snapshots: depd@2.0.0: {} - derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1)): + derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1)): dependencies: - valtio: 1.13.2(@types/react@19.1.13)(react@19.1.1) + valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) derive-valtio@0.1.0(valtio@1.13.2(react@19.1.1)): dependencies: @@ -18190,7 +16881,7 @@ snapshots: detect-browser@5.3.0: {} - detect-libc@2.1.1: {} + detect-libc@2.0.4: {} detect-node-es@1.1.0: {} @@ -18350,12 +17041,12 @@ snapshots: transitivePeerDependencies: - supports-color - electron-to-chromium@1.5.223: {} + electron-to-chromium@1.5.207: {} electron-winstaller@5.4.0: dependencies: '@electron/asar': 3.4.1 - debug: 4.4.3 + debug: 4.4.1 fs-extra: 7.0.1 lodash: 4.17.21 temp: 0.9.4 @@ -18364,10 +17055,10 @@ snapshots: transitivePeerDependencies: - supports-color - electron@37.5.1: + electron@37.3.1: dependencies: '@electron/get': 2.0.3 - '@types/node': 22.18.6 + '@types/node': 22.17.2 extract-zip: 2.0.1 transitivePeerDependencies: - supports-color @@ -18406,7 +17097,7 @@ snapshots: engine.io-client@6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.4 + debug: 4.3.7 engine.io-parser: 5.2.3 ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) xmlhttprequest-ssl: 2.1.2 @@ -18425,7 +17116,7 @@ snapshots: err-code@2.0.3: {} - error-ex@1.3.4: + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -18569,34 +17260,34 @@ snapshots: '@esbuild/win32-ia32': 0.19.12 '@esbuild/win32-x64': 0.19.12 - esbuild@0.25.10: + esbuild@0.25.9: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.10 - '@esbuild/android-arm': 0.25.10 - '@esbuild/android-arm64': 0.25.10 - '@esbuild/android-x64': 0.25.10 - '@esbuild/darwin-arm64': 0.25.10 - '@esbuild/darwin-x64': 0.25.10 - '@esbuild/freebsd-arm64': 0.25.10 - '@esbuild/freebsd-x64': 0.25.10 - '@esbuild/linux-arm': 0.25.10 - '@esbuild/linux-arm64': 0.25.10 - '@esbuild/linux-ia32': 0.25.10 - '@esbuild/linux-loong64': 0.25.10 - '@esbuild/linux-mips64el': 0.25.10 - '@esbuild/linux-ppc64': 0.25.10 - '@esbuild/linux-riscv64': 0.25.10 - '@esbuild/linux-s390x': 0.25.10 - '@esbuild/linux-x64': 0.25.10 - '@esbuild/netbsd-arm64': 0.25.10 - '@esbuild/netbsd-x64': 0.25.10 - '@esbuild/openbsd-arm64': 0.25.10 - '@esbuild/openbsd-x64': 0.25.10 - '@esbuild/openharmony-arm64': 0.25.10 - '@esbuild/sunos-x64': 0.25.10 - '@esbuild/win32-arm64': 0.25.10 - '@esbuild/win32-ia32': 0.25.10 - '@esbuild/win32-x64': 0.25.10 + '@esbuild/aix-ppc64': 0.25.9 + '@esbuild/android-arm': 0.25.9 + '@esbuild/android-arm64': 0.25.9 + '@esbuild/android-x64': 0.25.9 + '@esbuild/darwin-arm64': 0.25.9 + '@esbuild/darwin-x64': 0.25.9 + '@esbuild/freebsd-arm64': 0.25.9 + '@esbuild/freebsd-x64': 0.25.9 + '@esbuild/linux-arm': 0.25.9 + '@esbuild/linux-arm64': 0.25.9 + '@esbuild/linux-ia32': 0.25.9 + '@esbuild/linux-loong64': 0.25.9 + '@esbuild/linux-mips64el': 0.25.9 + '@esbuild/linux-ppc64': 0.25.9 + '@esbuild/linux-riscv64': 0.25.9 + '@esbuild/linux-s390x': 0.25.9 + '@esbuild/linux-x64': 0.25.9 + '@esbuild/netbsd-arm64': 0.25.9 + '@esbuild/netbsd-x64': 0.25.9 + '@esbuild/openbsd-arm64': 0.25.9 + '@esbuild/openbsd-x64': 0.25.9 + '@esbuild/openharmony-arm64': 0.25.9 + '@esbuild/sunos-x64': 0.25.9 + '@esbuild/win32-arm64': 0.25.9 + '@esbuild/win32-ia32': 0.25.9 + '@esbuild/win32-x64': 0.25.9 escalade@3.2.0: {} @@ -18604,19 +17295,19 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-next@15.1.7(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2): + eslint-config-next@15.1.7(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2): dependencies: '@next/eslint-plugin-next': 15.1.7 '@rushstack/eslint-patch': 1.12.0 - '@typescript-eslint/eslint-plugin': 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) - eslint: 9.36.0(jiti@1.21.7) + '@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + eslint: 9.33.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.36.0(jiti@1.21.7)) - eslint-plugin-react: 7.37.5(eslint@9.36.0(jiti@1.21.7)) - eslint-plugin-react-hooks: 5.2.0(eslint@9.36.0(jiti@1.21.7)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.33.0(jiti@1.21.7)) + eslint-plugin-react: 7.37.5(eslint@9.33.0(jiti@1.21.7)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.33.0(jiti@1.21.7)) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -18628,12 +17319,12 @@ snapshots: dependencies: '@next/eslint-plugin-next': 15.3.3 '@rushstack/eslint-patch': 1.12.0 - '@typescript-eslint/eslint-plugin': 8.44.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/parser': 8.44.1(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.5(eslint@8.57.1) eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1) @@ -18648,9 +17339,9 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)): + eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)): dependencies: - eslint: 9.36.0(jiti@1.21.7) + eslint: 9.33.0(jiti@1.21.7) optional: true eslint-import-resolver-node@0.3.9: @@ -18661,59 +17352,59 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.3 + debug: 4.4.1 eslint: 8.57.1 get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.15 + tinyglobby: 0.2.14 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)): dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.3 - eslint: 9.36.0(jiti@1.21.7) + debug: 4.4.1 + eslint: 9.33.0(jiti@1.21.7) get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.15 + tinyglobby: 0.2.14 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.44.1(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) - eslint: 9.36.0(jiti@1.21.7) + '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) + eslint: 9.33.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -18724,7 +17415,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -18736,13 +17427,13 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.44.1(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@1.21.7)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -18751,9 +17442,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.36.0(jiti@1.21.7) + eslint: 9.33.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -18765,20 +17456,20 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@1.21.7))(typescript@5.9.2) + '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsdoc@50.8.0(eslint@9.36.0(jiti@1.21.7)): + eslint-plugin-jsdoc@50.8.0(eslint@9.33.0(jiti@1.21.7)): dependencies: '@es-joy/jsdoccomment': 0.50.2 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.4.3 + debug: 4.4.1 escape-string-regexp: 4.0.0 - eslint: 9.36.0(jiti@1.21.7) + eslint: 9.33.0(jiti@1.21.7) espree: 10.4.0 esquery: 1.6.0 parse-imports-exports: 0.2.4 @@ -18806,7 +17497,7 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-jsx-a11y@6.10.2(eslint@9.36.0(jiti@1.21.7)): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.33.0(jiti@1.21.7)): dependencies: aria-query: 5.3.2 array-includes: 3.1.9 @@ -18816,7 +17507,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.36.0(jiti@1.21.7) + eslint: 9.33.0(jiti@1.21.7) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -18834,22 +17525,22 @@ snapshots: optionalDependencies: eslint-config-prettier: 10.1.8(eslint@8.57.1) - eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@1.21.7)))(eslint@9.36.0(jiti@1.21.7))(prettier@3.5.2): + eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7))(prettier@3.5.2): dependencies: - eslint: 9.36.0(jiti@1.21.7) + eslint: 9.33.0(jiti@1.21.7) prettier: 3.5.2 prettier-linter-helpers: 1.0.0 synckit: 0.11.11 optionalDependencies: - eslint-config-prettier: 10.1.8(eslint@9.36.0(jiti@1.21.7)) + eslint-config-prettier: 10.1.8(eslint@9.33.0(jiti@1.21.7)) eslint-plugin-react-hooks@5.2.0(eslint@8.57.1): dependencies: eslint: 8.57.1 - eslint-plugin-react-hooks@5.2.0(eslint@9.36.0(jiti@1.21.7)): + eslint-plugin-react-hooks@5.2.0(eslint@9.33.0(jiti@1.21.7)): dependencies: - eslint: 9.36.0(jiti@1.21.7) + eslint: 9.33.0(jiti@1.21.7) eslint-plugin-react@7.37.5(eslint@8.57.1): dependencies: @@ -18873,7 +17564,7 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-react@7.37.5(eslint@9.36.0(jiti@1.21.7)): + eslint-plugin-react@7.37.5(eslint@9.33.0(jiti@1.21.7)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -18881,7 +17572,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 9.36.0(jiti@1.21.7) + eslint: 9.33.0(jiti@1.21.7) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -18911,7 +17602,7 @@ snapshots: eslint@8.57.1: dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) '@eslint-community/regexpp': 4.12.1 '@eslint/eslintrc': 2.1.4 '@eslint/js': 8.57.1 @@ -18922,7 +17613,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.1 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -18952,17 +17643,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint@9.36.0(jiti@1.21.7): + eslint@9.33.0(jiti@1.21.7): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0(jiti@1.21.7)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@1.21.7)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 '@eslint/config-helpers': 0.3.1 '@eslint/core': 0.15.2 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.36.0 + '@eslint/js': 9.33.0 '@eslint/plugin-kit': 0.3.5 - '@humanfs/node': 0.16.7 + '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 @@ -18970,7 +17661,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.1 escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -19081,11 +17772,11 @@ snapshots: events@3.3.0: {} - eventsource-parser@3.0.6: {} + eventsource-parser@3.0.5: {} eventsource@3.0.7: dependencies: - eventsource-parser: 3.0.6 + eventsource-parser: 3.0.5 execa@5.1.1: dependencies: @@ -19151,7 +17842,7 @@ snapshots: content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.2.2 - debug: 4.4.3 + debug: 4.4.1 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -19182,7 +17873,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.4.3 + debug: 4.4.1 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -19227,7 +17918,7 @@ snapshots: fast-stable-stringify@1.0.0: {} - fast-uri@3.1.0: {} + fast-uri@3.0.6: {} fastestsmallesttextencoderdecoder@1.0.22: {} @@ -19284,7 +17975,7 @@ snapshots: finalhandler@2.1.0: dependencies: - debug: 4.4.3 + debug: 4.4.1 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 @@ -19305,9 +17996,9 @@ snapshots: fix-dts-default-cjs-exports@1.0.1: dependencies: - magic-string: 0.30.19 - mlly: 1.8.0 - rollup: 4.52.2 + magic-string: 0.30.17 + mlly: 1.7.4 + rollup: 4.46.4 flat-cache@3.2.0: dependencies: @@ -19366,7 +18057,7 @@ snapshots: jsonfile: 6.2.0 universalify: 2.0.1 - fs-extra@11.3.2: + fs-extra@11.3.1: dependencies: graceful-fs: 4.2.11 jsonfile: 6.2.0 @@ -19560,7 +18251,7 @@ snapshots: defu: 6.1.4 destr: 2.0.5 iron-webcrypto: 1.2.1 - node-mock-http: 1.0.3 + node-mock-http: 1.0.2 radix3: 1.1.2 ufo: 1.6.1 uncrypto: 0.1.3 @@ -19583,12 +18274,11 @@ snapshots: dependencies: has-symbols: 1.1.0 - hash-base@3.1.2: + hash-base@3.1.0: dependencies: inherits: 2.0.4 - readable-stream: 2.3.8 + readable-stream: 3.6.2 safe-buffer: 5.2.1 - to-buffer: 1.2.2 hash.js@1.1.7: dependencies: @@ -19605,7 +18295,7 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - hono@4.9.8: {} + hono@4.9.2: {} hosted-git-info@4.1.0: dependencies: @@ -19644,14 +18334,14 @@ snapshots: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -19663,14 +18353,14 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -19694,10 +18384,6 @@ snapshots: dependencies: safer-buffer: 2.1.2 - iconv-lite@0.7.0: - dependencies: - safer-buffer: 2.1.2 - idb-keyval@6.2.1: {} idb-keyval@6.2.2: {} @@ -19751,7 +18437,7 @@ snapshots: is-arrayish@0.2.1: {} - is-arrayish@0.3.4: {} + is-arrayish@0.3.2: {} is-async-function@2.1.1: dependencies: @@ -19830,7 +18516,7 @@ snapshots: is-negative-zero@2.0.3: {} - is-network-error@1.3.0: {} + is-network-error@1.1.0: {} is-number-object@1.1.1: dependencies: @@ -19896,7 +18582,7 @@ snapshots: isbinaryfile@4.0.10: {} - isbinaryfile@5.0.6: {} + isbinaryfile@5.0.4: {} isexe@2.0.0: {} @@ -19957,7 +18643,7 @@ snapshots: jose@5.10.0: {} - jose@6.1.0: {} + jose@6.0.12: {} joycon@3.1.1: {} @@ -19984,7 +18670,7 @@ snapshots: http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.22 + nwsapi: 2.2.21 parse5: 7.3.0 rrweb-cssom: 0.8.0 saxes: 6.0.0 @@ -20002,6 +18688,8 @@ snapshots: - supports-color - utf-8-validate + jsesc@3.0.2: {} + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -20060,7 +18748,7 @@ snapshots: kuler@2.0.0: {} - langsmith@0.3.69(openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): + langsmith@0.3.62(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): dependencies: '@types/uuid': 10.0.0 chalk: 4.1.2 @@ -20070,7 +18758,7 @@ snapshots: semver: 7.7.2 uuid: 10.0.0 optionalDependencies: - openai: 5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + openai: 5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) language-subtag-registry@0.3.23: {} @@ -20087,7 +18775,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - libphonenumber-js@1.12.22: {} + libphonenumber-js@1.12.13: {} lilconfig@3.1.3: {} @@ -20118,7 +18806,7 @@ snapshots: '@llamaindex/openai': 0.3.7(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30)(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) '@llamaindex/workflow': 1.0.3(@llamaindex/core@0.6.5)(@llamaindex/env@0.1.30)(zod@3.25.76) '@types/lodash': 4.17.20 - '@types/node': 22.18.6 + '@types/node': 22.17.2 ajv: 8.17.1 lodash: 4.17.21 magic-bytes.js: 1.12.1 @@ -20143,6 +18831,8 @@ snapshots: lodash.debounce@4.0.8: {} + lodash.memoize@4.1.2: {} + lodash.merge@4.6.2: {} lodash.sortby@4.7.0: {} @@ -20167,7 +18857,7 @@ snapshots: dependencies: js-tokens: 4.0.0 - loupe@3.2.1: {} + loupe@3.2.0: {} lower-case@2.0.2: dependencies: @@ -20189,7 +18879,7 @@ snapshots: magic-bytes.js@1.12.1: {} - magic-string@0.30.19: + magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -20224,7 +18914,7 @@ snapshots: md5.js@1.3.5: dependencies: - hash-base: 3.1.2 + hash-base: 3.1.0 inherits: 2.0.4 safe-buffer: 5.2.1 @@ -20356,7 +19046,7 @@ snapshots: mkdirp@1.0.4: {} - mlly@1.8.0: + mlly@1.7.4: dependencies: acorn: 8.15.0 pathe: 2.0.3 @@ -20365,8 +19055,6 @@ snapshots: ms@2.0.0: {} - ms@2.1.2: {} - ms@2.1.3: {} multiformats@9.9.0: {} @@ -20391,25 +19079,25 @@ snapshots: negotiator@1.0.0: {} - next@15.5.4(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + next@15.5.0(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - '@next/env': 15.5.4 + '@next/env': 15.5.0 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001745 + caniuse-lite: 1.0.30001735 postcss: 8.4.31 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - styled-jsx: 5.1.6(@babel/core@7.28.4)(react@19.1.1) + styled-jsx: 5.1.6(@babel/core@7.28.3)(react@19.1.1) optionalDependencies: - '@next/swc-darwin-arm64': 15.5.4 - '@next/swc-darwin-x64': 15.5.4 - '@next/swc-linux-arm64-gnu': 15.5.4 - '@next/swc-linux-arm64-musl': 15.5.4 - '@next/swc-linux-x64-gnu': 15.5.4 - '@next/swc-linux-x64-musl': 15.5.4 - '@next/swc-win32-arm64-msvc': 15.5.4 - '@next/swc-win32-x64-msvc': 15.5.4 - sharp: 0.34.4 + '@next/swc-darwin-arm64': 15.5.0 + '@next/swc-darwin-x64': 15.5.0 + '@next/swc-linux-arm64-gnu': 15.5.0 + '@next/swc-linux-arm64-musl': 15.5.0 + '@next/swc-linux-x64-gnu': 15.5.0 + '@next/swc-linux-x64-musl': 15.5.0 + '@next/swc-win32-arm64-msvc': 15.5.0 + '@next/swc-win32-x64-msvc': 15.5.0 + sharp: 0.34.3 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -20419,7 +19107,7 @@ snapshots: lower-case: 2.0.2 tslib: 2.8.1 - node-abi@3.77.0: + node-abi@3.75.0: dependencies: semver: 7.7.2 @@ -20454,9 +19142,9 @@ snapshots: node-gyp-build@4.8.4: {} - node-mock-http@1.0.3: {} + node-mock-http@1.0.2: {} - node-releases@2.0.21: {} + node-releases@2.0.19: {} nopt@6.0.0: dependencies: @@ -20474,7 +19162,7 @@ snapshots: dependencies: boolbase: 1.0.0 - nwsapi@2.2.22: {} + nwsapi@2.2.21: {} obj-multiplex@1.0.0: dependencies: @@ -20552,7 +19240,7 @@ snapshots: openai@4.104.0(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): dependencies: - '@types/node': 18.19.127 + '@types/node': 18.19.123 '@types/node-fetch': 2.6.13 abort-controller: 3.0.0 agentkeepalive: 4.6.0 @@ -20565,17 +19253,11 @@ snapshots: transitivePeerDependencies: - encoding - openai@5.23.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): + openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): optionalDependencies: ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) zod: 3.25.76 - openapi-fetch@0.13.8: - dependencies: - openapi-typescript-helpers: 0.0.15 - - openapi-typescript-helpers@0.0.15: {} - opensea-js@7.2.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@opensea/seaport-js': 4.0.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -20605,165 +19287,93 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 - own-keys@1.0.1: - dependencies: - get-intrinsic: 1.3.0 - object-keys: 1.1.1 - safe-push-apply: 1.0.0 - - ox@0.4.4(typescript@5.9.2)(zod@3.25.76): - 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.1.1(typescript@5.9.2)(zod@3.25.76) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - zod - - ox@0.4.4(typescript@5.9.2)(zod@4.1.11): - 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.1.1(typescript@5.9.2)(zod@4.1.11) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - zod - - ox@0.6.7(typescript@5.9.2)(zod@3.25.76): - dependencies: - '@adraffy/ens-normalize': 1.11.1 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@scure/bip32': 1.6.2 - '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.9.2)(zod@3.25.76) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - zod - - ox@0.6.7(typescript@5.9.2)(zod@4.1.11): - dependencies: - '@adraffy/ens-normalize': 1.11.1 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@scure/bip32': 1.6.2 - '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.9.2)(zod@4.1.11) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - zod - - ox@0.6.9(typescript@5.9.2)(zod@3.25.76): - 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.1.1(typescript@5.9.2)(zod@3.25.76) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - zod + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 - ox@0.6.9(typescript@5.9.2)(zod@4.1.11): + ox@0.4.4(typescript@5.9.2)(zod@3.25.76): dependencies: - '@adraffy/ens-normalize': 1.11.1 + '@adraffy/ens-normalize': 1.11.0 '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.1(typescript@5.9.2)(zod@4.1.11) + abitype: 1.0.9(typescript@5.9.2)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: - zod - ox@0.8.1(typescript@5.9.2)(zod@3.25.76): + ox@0.6.7(typescript@5.9.2)(zod@3.25.76): dependencies: - '@adraffy/ens-normalize': 1.11.1 - '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.7 + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.8.1 '@noble/hashes': 1.8.0 - '@scure/bip32': 1.7.0 - '@scure/bip39': 1.6.0 - abitype: 1.1.1(typescript@5.9.2)(zod@3.25.76) + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.9.2)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: - zod - ox@0.9.6(typescript@5.9.2)(zod@3.22.4): + ox@0.6.9(typescript@5.9.2)(zod@3.25.76): dependencies: - '@adraffy/ens-normalize': 1.11.1 - '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.1 + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.2)(zod@3.22.4) + abitype: 1.0.9(typescript@5.9.2)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: - zod - ox@0.9.6(typescript@5.9.2)(zod@3.25.76): + ox@0.8.1(typescript@5.9.2)(zod@3.25.76): dependencies: - '@adraffy/ens-normalize': 1.11.1 + '@adraffy/ens-normalize': 1.11.0 '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.2)(zod@3.25.76) + abitype: 1.0.9(typescript@5.9.2)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: - zod - ox@0.9.6(typescript@5.9.2)(zod@4.1.11): + ox@0.8.7(typescript@5.9.2)(zod@3.22.4): dependencies: - '@adraffy/ens-normalize': 1.11.1 + '@adraffy/ens-normalize': 1.11.0 '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.6 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.2)(zod@4.1.11) + abitype: 1.0.8(typescript@5.9.2)(zod@3.22.4) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: - zod - ox@0.9.7(typescript@5.9.2)(zod@4.1.11): + ox@0.8.7(typescript@5.9.2)(zod@3.25.76): dependencies: - '@adraffy/ens-normalize': 1.11.1 + '@adraffy/ens-normalize': 1.11.0 '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.6 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.1(typescript@5.9.2)(zod@4.1.11) + abitype: 1.0.8(typescript@5.9.2)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 @@ -20807,7 +19417,7 @@ snapshots: p-retry@6.2.1: dependencies: '@types/retry': 0.12.2 - is-network-error: 1.3.0 + is-network-error: 1.1.0 retry: 0.13.1 p-timeout@3.2.0: @@ -20829,7 +19439,7 @@ snapshots: parse-json@5.2.0: dependencies: '@babel/code-frame': 7.27.1 - error-ex: 1.3.4 + error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -20861,7 +19471,7 @@ snapshots: path-to-regexp@0.1.12: {} - path-to-regexp@8.3.0: {} + path-to-regexp@8.2.0: {} path-type@4.0.0: {} @@ -20917,7 +19527,7 @@ snapshots: pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.8.0 + mlly: 1.7.4 pathe: 2.0.3 plist@3.1.0: @@ -20930,106 +19540,6 @@ snapshots: pony-cause@2.1.11: {} - porto@0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11)): - dependencies: - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - hono: 4.9.8 - idb-keyval: 6.2.2 - mipd: 0.0.7(typescript@5.9.2) - ox: 0.9.7(typescript@5.9.2)(zod@4.1.11) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - zod: 4.1.11 - zustand: 5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) - optionalDependencies: - '@tanstack/react-query': 5.90.2(react@19.1.1) - react: 19.1.1 - typescript: 5.9.2 - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) - transitivePeerDependencies: - - '@types/react' - - immer - - use-sync-external-store - - porto@0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)): - dependencies: - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - hono: 4.9.8 - idb-keyval: 6.2.2 - mipd: 0.0.7(typescript@5.9.2) - ox: 0.9.7(typescript@5.9.2)(zod@4.1.11) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zod: 4.1.11 - zustand: 5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) - optionalDependencies: - '@tanstack/react-query': 5.90.2(react@19.1.1) - react: 19.1.1 - typescript: 5.9.2 - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) - transitivePeerDependencies: - - '@types/react' - - immer - - use-sync-external-store - - porto@0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)): - dependencies: - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - hono: 4.9.8 - idb-keyval: 6.2.2 - mipd: 0.0.7(typescript@5.9.2) - ox: 0.9.7(typescript@5.9.2)(zod@4.1.11) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zod: 4.1.11 - zustand: 5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) - optionalDependencies: - '@tanstack/react-query': 5.90.2(react@19.1.1) - react: 19.1.1 - typescript: 5.9.2 - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) - transitivePeerDependencies: - - '@types/react' - - immer - - use-sync-external-store - - porto@0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11)): - dependencies: - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - hono: 4.9.8 - idb-keyval: 6.2.2 - mipd: 0.0.7(typescript@5.9.2) - ox: 0.9.7(typescript@5.9.2)(zod@4.1.11) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - zod: 4.1.11 - zustand: 5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) - optionalDependencies: - '@tanstack/react-query': 5.90.2(react@19.1.1) - react: 19.1.1 - typescript: 5.9.2 - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11) - transitivePeerDependencies: - - '@types/react' - - immer - - use-sync-external-store - - porto@0.2.19(@tanstack/react-query@5.90.2(react@19.1.1))(@wagmi/core@2.21.1(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76)): - dependencies: - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - hono: 4.9.8 - idb-keyval: 6.2.2 - mipd: 0.0.7(typescript@5.9.2) - ox: 0.9.7(typescript@5.9.2)(zod@4.1.11) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - zod: 4.1.11 - zustand: 5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) - optionalDependencies: - '@tanstack/react-query': 5.90.2(react@19.1.1) - react: 19.1.1 - typescript: 5.9.2 - wagmi: 2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76) - transitivePeerDependencies: - - '@types/react' - - immer - - use-sync-external-store - possible-typed-array-names@1.1.0: {} postcss-import@15.1.0(postcss@8.5.6): @@ -21039,7 +19549,7 @@ snapshots: read-cache: 1.0.0 resolve: 1.22.10 - postcss-js@4.1.0(postcss@8.5.6): + postcss-js@4.0.1(postcss@8.5.6): dependencies: camelcase-css: 2.0.1 postcss: 8.5.6 @@ -21051,13 +19561,13 @@ snapshots: optionalDependencies: postcss: 8.5.6 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(yaml@2.8.1): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(yaml@2.8.1): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 postcss: 8.5.6 - tsx: 4.20.5 + tsx: 4.20.4 yaml: 2.8.1 postcss-nested@6.2.0(postcss@8.5.6): @@ -21091,7 +19601,7 @@ snapshots: preact@10.24.2: {} - preact@10.27.2: {} + preact@10.27.1: {} prelude-ls@1.2.1: {} @@ -21178,68 +19688,68 @@ snapshots: quick-lru@5.1.1: {} - radix-ui@1.4.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + radix-ui@1.4.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-accessible-icon': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-alert-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-aspect-ratio': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-avatar': 1.1.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-context-menu': 2.2.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-form': 0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-label': 2.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-menubar': 1.1.16(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-password-toggle-field': 0.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-progress': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-radio-group': 1.3.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-select': 2.2.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slider': 1.3.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-switch': 1.2.6(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toolbar': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-tooltip': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-accessible-icon': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-alert-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-aspect-ratio': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-avatar': 1.1.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-context-menu': 2.2.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-form': 0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-label': 2.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-menubar': 1.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-password-toggle-field': 0.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-progress': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-radio-group': 1.3.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-select': 2.2.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slider': 1.3.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-switch': 1.2.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toolbar': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tooltip': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 - '@types/react-dom': 19.1.9(@types/react@19.1.13) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) radix3@1.1.2: {} @@ -21252,11 +19762,11 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-body@3.0.1: + raw-body@3.0.0: dependencies: bytes: 3.1.2 http-errors: 2.0.0 - iconv-lite: 0.7.0 + iconv-lite: 0.6.3 unpipe: 1.0.0 react-dom@18.3.1(react@18.3.1): @@ -21287,59 +19797,32 @@ snapshots: react-refresh@0.17.0: {} - react-remove-scroll-bar@2.3.8(@types/react@19.1.13)(react@18.3.1): + react-remove-scroll-bar@2.3.8(@types/react@19.1.10)(react@18.3.1): dependencies: react: 18.3.1 - react-style-singleton: 2.2.3(@types/react@19.1.13)(react@18.3.1) - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.1.13 - - react-remove-scroll-bar@2.3.8(@types/react@19.1.13)(react@19.1.1): - dependencies: - react: 19.1.1 - react-style-singleton: 2.2.3(@types/react@19.1.13)(react@19.1.1) + react-style-singleton: 2.2.3(@types/react@19.1.10)(react@18.3.1) tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - react-remove-scroll@2.7.1(@types/react@19.1.13)(react@18.3.1): + react-remove-scroll@2.7.1(@types/react@19.1.10)(react@18.3.1): dependencies: react: 18.3.1 - react-remove-scroll-bar: 2.3.8(@types/react@19.1.13)(react@18.3.1) - react-style-singleton: 2.2.3(@types/react@19.1.13)(react@18.3.1) - tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.1.13)(react@18.3.1) - use-sidecar: 1.1.3(@types/react@19.1.13)(react@18.3.1) - optionalDependencies: - '@types/react': 19.1.13 - - react-remove-scroll@2.7.1(@types/react@19.1.13)(react@19.1.1): - dependencies: - react: 19.1.1 - react-remove-scroll-bar: 2.3.8(@types/react@19.1.13)(react@19.1.1) - react-style-singleton: 2.2.3(@types/react@19.1.13)(react@19.1.1) + react-remove-scroll-bar: 2.3.8(@types/react@19.1.10)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@19.1.10)(react@18.3.1) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.1.13)(react@19.1.1) - use-sidecar: 1.1.3(@types/react@19.1.13)(react@19.1.1) + use-callback-ref: 1.3.3(@types/react@19.1.10)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@19.1.10)(react@18.3.1) optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - react-style-singleton@2.2.3(@types/react@19.1.13)(react@18.3.1): + react-style-singleton@2.2.3(@types/react@19.1.10)(react@18.3.1): dependencies: get-nonce: 1.0.1 react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.13 - - react-style-singleton@2.2.3(@types/react@19.1.13)(react@19.1.1): - dependencies: - get-nonce: 1.0.1 - react: 19.1.1 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 react@18.3.1: dependencies: @@ -21349,7 +19832,7 @@ snapshots: read-binary-file-arch@1.0.6: dependencies: - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -21396,7 +19879,7 @@ snapshots: get-proto: 1.0.1 which-builtin-type: 1.2.1 - regenerate-unicode-properties@10.2.2: + regenerate-unicode-properties@10.2.0: dependencies: regenerate: 1.4.2 @@ -21411,22 +19894,22 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 - regexpu-core@6.4.0: + regexpu-core@6.2.0: dependencies: regenerate: 1.4.2 - regenerate-unicode-properties: 10.2.2 + regenerate-unicode-properties: 10.2.0 regjsgen: 0.8.0 - regjsparser: 0.13.0 + regjsparser: 0.12.0 unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.2.1 + unicode-match-property-value-ecmascript: 2.2.0 regjsgen@0.8.0: {} - regjsparser@0.13.0: + regjsparser@0.12.0: dependencies: - jsesc: 3.1.0 + jsesc: 3.0.2 - remeda@2.32.0: + remeda@2.30.0: dependencies: type-fest: 4.41.0 @@ -21485,9 +19968,9 @@ snapshots: dependencies: glob: 7.2.3 - ripemd160@2.0.3: + ripemd160@2.0.2: dependencies: - hash-base: 3.1.2 + hash-base: 3.1.0 inherits: 2.0.4 roarr@2.15.4: @@ -21500,45 +19983,43 @@ snapshots: sprintf-js: 1.1.3 optional: true - rollup@4.52.2: + rollup@4.46.4: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.52.2 - '@rollup/rollup-android-arm64': 4.52.2 - '@rollup/rollup-darwin-arm64': 4.52.2 - '@rollup/rollup-darwin-x64': 4.52.2 - '@rollup/rollup-freebsd-arm64': 4.52.2 - '@rollup/rollup-freebsd-x64': 4.52.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.52.2 - '@rollup/rollup-linux-arm-musleabihf': 4.52.2 - '@rollup/rollup-linux-arm64-gnu': 4.52.2 - '@rollup/rollup-linux-arm64-musl': 4.52.2 - '@rollup/rollup-linux-loong64-gnu': 4.52.2 - '@rollup/rollup-linux-ppc64-gnu': 4.52.2 - '@rollup/rollup-linux-riscv64-gnu': 4.52.2 - '@rollup/rollup-linux-riscv64-musl': 4.52.2 - '@rollup/rollup-linux-s390x-gnu': 4.52.2 - '@rollup/rollup-linux-x64-gnu': 4.52.2 - '@rollup/rollup-linux-x64-musl': 4.52.2 - '@rollup/rollup-openharmony-arm64': 4.52.2 - '@rollup/rollup-win32-arm64-msvc': 4.52.2 - '@rollup/rollup-win32-ia32-msvc': 4.52.2 - '@rollup/rollup-win32-x64-gnu': 4.52.2 - '@rollup/rollup-win32-x64-msvc': 4.52.2 + '@rollup/rollup-android-arm-eabi': 4.46.4 + '@rollup/rollup-android-arm64': 4.46.4 + '@rollup/rollup-darwin-arm64': 4.46.4 + '@rollup/rollup-darwin-x64': 4.46.4 + '@rollup/rollup-freebsd-arm64': 4.46.4 + '@rollup/rollup-freebsd-x64': 4.46.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.46.4 + '@rollup/rollup-linux-arm-musleabihf': 4.46.4 + '@rollup/rollup-linux-arm64-gnu': 4.46.4 + '@rollup/rollup-linux-arm64-musl': 4.46.4 + '@rollup/rollup-linux-loongarch64-gnu': 4.46.4 + '@rollup/rollup-linux-ppc64-gnu': 4.46.4 + '@rollup/rollup-linux-riscv64-gnu': 4.46.4 + '@rollup/rollup-linux-riscv64-musl': 4.46.4 + '@rollup/rollup-linux-s390x-gnu': 4.46.4 + '@rollup/rollup-linux-x64-gnu': 4.46.4 + '@rollup/rollup-linux-x64-musl': 4.46.4 + '@rollup/rollup-win32-arm64-msvc': 4.46.4 + '@rollup/rollup-win32-ia32-msvc': 4.46.4 + '@rollup/rollup-win32-x64-msvc': 4.46.4 fsevents: 2.3.3 router@2.2.0: dependencies: - debug: 4.4.3 + debug: 4.4.1 depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 - path-to-regexp: 8.3.0 + path-to-regexp: 8.2.0 transitivePeerDependencies: - supports-color - rpc-websockets@9.2.0: + rpc-websockets@9.1.3: dependencies: '@swc/helpers': 0.5.17 '@types/uuid': 8.3.4 @@ -21643,7 +20124,7 @@ snapshots: send@1.2.0: dependencies: - debug: 4.4.3 + debug: 4.4.1 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -21710,36 +20191,36 @@ snapshots: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 - to-buffer: 1.2.2 + to-buffer: 1.2.1 - sharp@0.34.4: + sharp@0.34.3: dependencies: - '@img/colour': 1.0.0 - detect-libc: 2.1.1 + color: 4.2.3 + detect-libc: 2.0.4 semver: 7.7.2 optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.4 - '@img/sharp-darwin-x64': 0.34.4 - '@img/sharp-libvips-darwin-arm64': 1.2.3 - '@img/sharp-libvips-darwin-x64': 1.2.3 - '@img/sharp-libvips-linux-arm': 1.2.3 - '@img/sharp-libvips-linux-arm64': 1.2.3 - '@img/sharp-libvips-linux-ppc64': 1.2.3 - '@img/sharp-libvips-linux-s390x': 1.2.3 - '@img/sharp-libvips-linux-x64': 1.2.3 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 - '@img/sharp-libvips-linuxmusl-x64': 1.2.3 - '@img/sharp-linux-arm': 0.34.4 - '@img/sharp-linux-arm64': 0.34.4 - '@img/sharp-linux-ppc64': 0.34.4 - '@img/sharp-linux-s390x': 0.34.4 - '@img/sharp-linux-x64': 0.34.4 - '@img/sharp-linuxmusl-arm64': 0.34.4 - '@img/sharp-linuxmusl-x64': 0.34.4 - '@img/sharp-wasm32': 0.34.4 - '@img/sharp-win32-arm64': 0.34.4 - '@img/sharp-win32-ia32': 0.34.4 - '@img/sharp-win32-x64': 0.34.4 + '@img/sharp-darwin-arm64': 0.34.3 + '@img/sharp-darwin-x64': 0.34.3 + '@img/sharp-libvips-darwin-arm64': 1.2.0 + '@img/sharp-libvips-darwin-x64': 1.2.0 + '@img/sharp-libvips-linux-arm': 1.2.0 + '@img/sharp-libvips-linux-arm64': 1.2.0 + '@img/sharp-libvips-linux-ppc64': 1.2.0 + '@img/sharp-libvips-linux-s390x': 1.2.0 + '@img/sharp-libvips-linux-x64': 1.2.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 + '@img/sharp-libvips-linuxmusl-x64': 1.2.0 + '@img/sharp-linux-arm': 0.34.3 + '@img/sharp-linux-arm64': 0.34.3 + '@img/sharp-linux-ppc64': 0.34.3 + '@img/sharp-linux-s390x': 0.34.3 + '@img/sharp-linux-x64': 0.34.3 + '@img/sharp-linuxmusl-arm64': 0.34.3 + '@img/sharp-linuxmusl-x64': 0.34.3 + '@img/sharp-wasm32': 0.34.3 + '@img/sharp-win32-arm64': 0.34.3 + '@img/sharp-win32-ia32': 0.34.3 + '@img/sharp-win32-x64': 0.34.3 optional: true shebang-command@2.0.0: @@ -21784,9 +20265,9 @@ snapshots: signal-exit@4.1.0: {} - simple-swizzle@0.2.4: + simple-swizzle@0.2.2: dependencies: - is-arrayish: 0.3.4 + is-arrayish: 0.3.2 simple-update-notifier@2.0.0: dependencies: @@ -21821,7 +20302,7 @@ snapshots: socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.4 + debug: 4.3.7 engine.io-client: 6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) socket.io-parser: 4.2.4 transitivePeerDependencies: @@ -21832,14 +20313,14 @@ snapshots: socket.io-parser@4.2.4: dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.4 + debug: 4.3.7 transitivePeerDependencies: - supports-color socks-proxy-agent@7.0.0: dependencies: agent-base: 6.0.2 - debug: 4.4.3 + debug: 4.4.1 socks: 2.8.7 transitivePeerDependencies: - supports-color @@ -21927,7 +20408,7 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.2 + strip-ansi: 7.1.0 string.prototype.includes@2.0.1: dependencies: @@ -21991,9 +20472,9 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.2: + strip-ansi@7.1.0: dependencies: - ansi-regex: 6.2.2 + ansi-regex: 6.2.0 strip-bom@3.0.0: {} @@ -22005,12 +20486,12 @@ snapshots: dependencies: js-tokens: 9.0.1 - styled-jsx@5.1.6(@babel/core@7.28.4)(react@19.1.1): + styled-jsx@5.1.6(@babel/core@7.28.3)(react@19.1.1): dependencies: client-only: 0.0.1 react: 19.1.1 optionalDependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.28.3 sucrase@3.35.0: dependencies: @@ -22024,7 +20505,7 @@ snapshots: sumchecker@3.0.1: dependencies: - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -22054,10 +20535,10 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 - svix@1.76.1: + svix@1.74.1: dependencies: '@stablelib/base64': 1.0.1 - '@types/node': 22.18.6 + '@types/node': 22.17.2 es6-promise: 4.2.8 fast-sha256: 1.3.0 url-parse: 1.5.10 @@ -22069,12 +20550,8 @@ snapshots: dependencies: '@pkgr/core': 0.2.9 - tabbable@6.2.0: {} - tailwind-merge@2.6.0: {} - tailwind-merge@3.3.1: {} - tailwindcss@3.4.17: dependencies: '@alloc/quick-lru': 5.2.0 @@ -22093,7 +20570,7 @@ snapshots: picocolors: 1.1.1 postcss: 8.5.6 postcss-import: 15.1.0(postcss@8.5.6) - postcss-js: 4.1.0(postcss@8.5.6) + postcss-js: 4.0.1(postcss@8.5.6) postcss-load-config: 4.0.2(postcss@8.5.6) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 @@ -22147,7 +20624,7 @@ snapshots: tinyexec@0.3.2: {} - tinyglobby@0.2.15: + tinyglobby@0.2.14: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 @@ -22156,7 +20633,7 @@ snapshots: tinyrainbow@2.0.0: {} - tinyspy@4.0.4: {} + tinyspy@4.0.3: {} tldts-core@6.1.86: {} @@ -22170,7 +20647,7 @@ snapshots: tmp@0.2.5: {} - to-buffer@1.2.2: + to-buffer@1.2.1: dependencies: isarray: 2.0.5 safe-buffer: 5.2.1 @@ -22245,14 +20722,14 @@ snapshots: bundle-require: 4.2.1(esbuild@0.19.12) cac: 6.7.14 chokidar: 3.6.0 - debug: 4.4.3 + debug: 4.4.1 esbuild: 0.19.12 execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 postcss-load-config: 4.0.2(postcss@8.5.6) resolve-from: 5.0.0 - rollup: 4.52.2 + rollup: 4.46.4 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tree-kill: 1.2.2 @@ -22263,24 +20740,24 @@ snapshots: - supports-color - ts-node - tsup@8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(typescript@5.9.2)(yaml@2.8.1): + tsup@8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(typescript@5.9.2)(yaml@2.8.1): dependencies: - bundle-require: 5.1.0(esbuild@0.25.10) + bundle-require: 5.1.0(esbuild@0.25.9) cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.2 - debug: 4.4.3 - esbuild: 0.25.10 + debug: 4.4.1 + esbuild: 0.25.9 fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.5)(yaml@2.8.1) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.4)(yaml@2.8.1) resolve-from: 5.0.0 - rollup: 4.52.2 + rollup: 4.46.4 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tinyexec: 0.3.2 - tinyglobby: 0.2.15 + tinyglobby: 0.2.14 tree-kill: 1.2.2 optionalDependencies: postcss: 8.5.6 @@ -22291,43 +20768,43 @@ snapshots: - tsx - yaml - tsx@4.20.5: + tsx@4.20.4: dependencies: - esbuild: 0.25.10 + esbuild: 0.25.9 get-tsconfig: 4.10.1 optionalDependencies: fsevents: 2.3.3 - turbo-darwin-64@2.5.8: + turbo-darwin-64@2.5.6: optional: true - turbo-darwin-arm64@2.5.8: + turbo-darwin-arm64@2.5.6: optional: true - turbo-linux-64@2.5.8: + turbo-linux-64@2.5.6: optional: true - turbo-linux-arm64@2.5.8: + turbo-linux-arm64@2.5.6: optional: true - turbo-windows-64@2.5.8: + turbo-windows-64@2.5.6: optional: true - turbo-windows-arm64@2.5.8: + turbo-windows-arm64@2.5.6: optional: true - turbo@2.5.8: + turbo@2.5.6: optionalDependencies: - turbo-darwin-64: 2.5.8 - turbo-darwin-arm64: 2.5.8 - turbo-linux-64: 2.5.8 - turbo-linux-arm64: 2.5.8 - turbo-windows-64: 2.5.8 - turbo-windows-arm64: 2.5.8 + turbo-darwin-64: 2.5.6 + turbo-darwin-arm64: 2.5.6 + turbo-linux-64: 2.5.6 + turbo-linux-arm64: 2.5.6 + turbo-windows-64: 2.5.6 + turbo-windows-arm64: 2.5.6 tweetnacl@1.0.3: {} - twitter-api-v2@1.27.0: {} + twitter-api-v2@1.25.0: {} type-check@0.4.0: dependencies: @@ -22411,20 +20888,20 @@ snapshots: undici-types@6.21.0: {} - undici-types@7.12.0: {} + undici-types@7.10.0: {} - undici-types@7.16.0: {} + undici-types@7.14.0: {} unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-match-property-ecmascript@2.0.0: dependencies: unicode-canonical-property-names-ecmascript: 2.0.1 - unicode-property-aliases-ecmascript: 2.2.0 + unicode-property-aliases-ecmascript: 2.1.0 - unicode-match-property-value-ecmascript@2.2.1: {} + unicode-match-property-value-ecmascript@2.2.0: {} - unicode-property-aliases-ecmascript@2.2.0: {} + unicode-property-aliases-ecmascript@2.1.0: {} unique-filename@2.0.1: dependencies: @@ -22464,7 +20941,7 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - unstorage@1.17.1(@upstash/redis@1.35.4)(idb-keyval@6.2.2): + unstorage@1.16.1(@upstash/redis@1.35.3)(idb-keyval@6.2.2): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 @@ -22475,12 +20952,12 @@ snapshots: ofetch: 1.4.1 ufo: 1.6.1 optionalDependencies: - '@upstash/redis': 1.35.4 + '@upstash/redis': 1.35.3 idb-keyval: 6.2.2 - update-browserslist-db@1.1.3(browserslist@4.26.2): + update-browserslist-db@1.1.3(browserslist@4.25.3): dependencies: - browserslist: 4.26.2 + browserslist: 4.25.3 escalade: 3.2.0 picocolors: 1.1.1 @@ -22493,35 +20970,20 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - use-callback-ref@1.3.3(@types/react@19.1.13)(react@18.3.1): + use-callback-ref@1.3.3(@types/react@19.1.10)(react@18.3.1): dependencies: react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.13 - - use-callback-ref@1.3.3(@types/react@19.1.13)(react@19.1.1): - dependencies: - react: 19.1.1 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 - use-sidecar@1.1.3(@types/react@19.1.13)(react@18.3.1): + use-sidecar@1.1.3(@types/react@19.1.10)(react@18.3.1): dependencies: detect-node-es: 1.1.0 react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.13 - - use-sidecar@1.1.3(@types/react@19.1.13)(react@19.1.1): - dependencies: - detect-node-es: 1.1.0 - react: 19.1.1 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 use-sync-external-store@1.2.0(react@19.1.1): dependencies: @@ -22540,11 +21002,6 @@ snapshots: react: 19.1.1 optional: true - usehooks-ts@3.1.1(react@19.1.1): - dependencies: - lodash.debounce: 4.0.8 - react: 19.1.1 - utf-8-validate@5.0.10: dependencies: node-gyp-build: 4.8.4 @@ -22571,13 +21028,13 @@ snapshots: valid-url@1.0.9: {} - valtio@1.13.2(@types/react@19.1.13)(react@19.1.1): + valtio@1.13.2(@types/react@19.1.10)(react@19.1.1): dependencies: - derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.1.13)(react@19.1.1)) + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1)) proxy-compare: 2.6.0 use-sync-external-store: 1.2.0(react@19.1.1) optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 react: 19.1.1 valtio@1.13.2(react@19.1.1): @@ -22614,49 +21071,15 @@ snapshots: - utf-8-validate - zod - viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11): - dependencies: - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@scure/bip32': 1.6.2 - '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.9.2)(zod@4.1.11) - isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.6.7(typescript@5.9.2)(zod@4.1.11) - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - zod - - viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(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.1.0(typescript@5.9.2)(zod@3.22.4) - isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.9.6(typescript@5.9.2)(zod@3.22.4) - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - zod - - viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76): + viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4): dependencies: - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.6 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.2)(zod@3.25.76) + abitype: 1.0.8(typescript@5.9.2)(zod@3.22.4) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.9.6(typescript@5.9.2)(zod@3.25.76) + ox: 0.8.7(typescript@5.9.2)(zod@3.22.4) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.2 @@ -22665,15 +21088,15 @@ snapshots: - utf-8-validate - zod - viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11): + viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.6 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.2)(zod@4.1.11) + abitype: 1.0.8(typescript@5.9.2)(zod@3.25.76) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.9.6(typescript@5.9.2)(zod@4.1.11) + ox: 0.8.7(typescript@5.9.2)(zod@3.25.76) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.2 @@ -22682,13 +21105,13 @@ snapshots: - utf-8-validate - zod - vite-node@3.2.4(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1): + vite-node@3.2.4(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1): dependencies: cac: 6.7.14 - debug: 4.4.3 + debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -22703,81 +21126,81 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)): dependencies: - debug: 4.4.3 + debug: 4.4.1 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.2) optionalDependencies: - vite: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript - vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1): + vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1): dependencies: - esbuild: 0.25.10 + esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.52.2 - tinyglobby: 0.2.15 + rollup: 4.46.4 + tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 22.18.6 + '@types/node': 22.17.2 fsevents: 2.3.3 jiti: 1.21.7 - tsx: 4.20.5 + tsx: 4.20.4 yaml: 2.8.1 - vite@7.1.7(@types/node@24.5.2)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1): + vite@7.1.3(@types/node@24.3.0)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1): dependencies: - esbuild: 0.25.10 + esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.52.2 - tinyglobby: 0.2.15 + rollup: 4.46.4 + tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 24.5.2 + '@types/node': 24.3.0 fsevents: 2.3.3 jiti: 1.21.7 - tsx: 4.20.5 + tsx: 4.20.4 yaml: 2.8.1 - vitest-mock-extended@3.1.0(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1)): + vitest-mock-extended@3.1.0(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1)): dependencies: ts-essentials: 10.1.1(typescript@5.9.2) typescript: 5.9.2 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1) - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.6)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.5)(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.17.2)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.4)(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.3.3 - debug: 4.4.3 + chai: 5.3.1 + debug: 4.4.1 expect-type: 1.2.2 - magic-string: 0.30.19 + magic-string: 0.30.17 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.15 + tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.6(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@22.18.6)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 22.18.6 + '@types/node': 22.17.2 jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - jiti @@ -22797,92 +21220,14 @@ snapshots: dependencies: xml-name-validator: 5.0.0 - wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): - dependencies: - '@tanstack/react-query': 5.90.2(react@19.1.1) - '@wagmi/connectors': 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - react: 19.1.1 - use-sync-external-store: 1.4.0(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - optionalDependencies: - typescript: 5.9.2 - 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' - - '@tanstack/query-core' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - immer - - ioredis - - supports-color - - uploadthing - - utf-8-validate - - zod - - wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76): - dependencies: - '@tanstack/react-query': 5.90.2(react@19.1.1) - '@wagmi/connectors': 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@3.25.76) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) - react: 19.1.1 - use-sync-external-store: 1.4.0(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) - optionalDependencies: - typescript: 5.9.2 - 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' - - '@tanstack/query-core' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - immer - - ioredis - - supports-color - - uploadthing - - utf-8-validate - - zod - - wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11): + wagmi@2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): dependencies: - '@tanstack/react-query': 5.90.2(react@19.1.1) - '@wagmi/connectors': 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@tanstack/react-query': 5.85.5(react@19.1.1) + '@wagmi/connectors': 5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -22901,7 +21246,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -22914,14 +21258,14 @@ snapshots: - utf-8-validate - zod - wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11): + wagmi@2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): dependencies: - '@tanstack/react-query': 5.90.2(react@19.1.1) - '@wagmi/connectors': 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@wagmi/core@2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@4.1.11))(zod@4.1.11) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@tanstack/react-query': 5.85.5(react@19.1.1) + '@wagmi/connectors': 5.9.4(@types/react@19.1.10)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -22940,7 +21284,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -22953,14 +21296,14 @@ snapshots: - utf-8-validate - zod - wagmi@2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76): + wagmi@2.16.4(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): dependencies: - '@tanstack/react-query': 5.90.2(react@19.1.1) - '@wagmi/connectors': 5.11.1(@tanstack/react-query@5.90.2(react@19.1.1))(@wagmi/core@2.21.1(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(wagmi@2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76))(zod@3.25.76) - '@wagmi/core': 2.21.1(@tanstack/query-core@5.90.2)(@types/react@19.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11)) + '@tanstack/react-query': 5.85.5(react@19.1.1) + '@wagmi/connectors': 5.9.4(@wagmi/core@2.19.0(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -22979,7 +21322,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -23124,9 +21466,9 @@ snapshots: wrap-ansi@8.1.0: dependencies: - ansi-styles: 6.2.3 + ansi-styles: 6.2.1 string-width: 5.1.2 - strip-ansi: 7.1.2 + strip-ansi: 7.1.0 wrappy@1.0.2: {} @@ -23152,8 +21494,8 @@ snapshots: x402-axios@0.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - axios: 1.12.2 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + axios: 1.11.0 + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: 0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: @@ -23166,7 +21508,7 @@ snapshots: x402-fetch@0.3.3(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: 0.3.7(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: @@ -23174,10 +21516,10 @@ snapshots: - typescript - utf-8-validate - x402-fetch@0.4.2(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): + x402-fetch@0.4.2(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - x402: 0.4.3(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + x402: 0.4.3(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -23196,7 +21538,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -23212,8 +21553,8 @@ snapshots: x402-hono@0.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - hono: 4.9.8 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + hono: 4.9.2 + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: 0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: @@ -23226,8 +21567,8 @@ snapshots: x402-hono@0.3.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - hono: 4.9.8 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + hono: 4.9.2 + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: 0.3.7(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: @@ -23237,9 +21578,9 @@ snapshots: x402@0.2.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - '@coinbase/cdp-sdk': 1.38.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) - axios: 1.12.2 - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/cdp-sdk': 1.36.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10) + axios: 1.11.0 + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -23251,59 +21592,17 @@ snapshots: x402@0.3.7(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - zod: 3.25.76 - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - x402@0.4.3(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): - dependencies: - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 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' - - '@tanstack/query-core' - - '@tanstack/react-query' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - bufferutil - - db0 - - encoding - - immer - - ioredis - - react - - supports-color - typescript - - uploadthing - utf-8-validate - x402@0.6.1(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): + x402@0.4.3(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: - '@scure/base': 1.2.6 - '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(typescript@5.9.2)) - '@solana-program/token': 0.5.1(@solana/kit@2.3.0(typescript@5.9.2)) - '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(typescript@5.9.2))(@solana/sysvars@2.3.0(typescript@5.9.2)) - '@solana/kit': 2.3.0(typescript@5.9.2) - '@solana/transaction-confirmation': 2.3.0(typescript@5.9.2) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.17.4(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.1))(@types/react@19.1.13)(@upstash/redis@1.35.4)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -23317,19 +21616,16 @@ snapshots: - '@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/functions' - '@vercel/kv' - aws4fetch - bufferutil - db0 - encoding - - fastestsmallesttextencoderdecoder - immer - ioredis - react @@ -23337,9 +21633,8 @@ snapshots: - typescript - uploadthing - utf-8-validate - - ws - x402@file:../../typescript/packages/x402(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): + x402@file:../../typescript/packages/x402(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): dependencies: '@scure/base': 1.2.6 '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(typescript@5.9.2)) @@ -23347,8 +21642,8 @@ snapshots: '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(typescript@5.9.2))(@solana/sysvars@2.3.0(typescript@5.9.2)) '@solana/kit': 2.3.0(typescript@5.9.2) '@solana/transaction-confirmation': 2.3.0(typescript@5.9.2) - viem: 2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.17.4(@tanstack/react-query@5.90.2(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.37.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@4.1.11))(zod@3.25.76) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.16.4(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -23368,7 +21663,6 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' - - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -23450,46 +21744,32 @@ snapshots: zod@3.25.76: {} - zod@4.1.11: {} - - zustand@5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): + zustand@5.0.0(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) - zustand@5.0.0(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): + zustand@5.0.0(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 react: 19.1.1 use-sync-external-store: 1.5.0(react@19.1.1) - zustand@5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): + zustand@5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) - zustand@5.0.3(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): + zustand@5.0.3(@types/react@19.1.10)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 react: 19.1.1 use-sync-external-store: 1.5.0(react@19.1.1) - zustand@5.0.8(@types/react@19.1.13)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)): + zustand@5.0.8(@types/react@19.1.10)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)): optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.10 react: 18.3.1 use-sync-external-store: 1.5.0(react@18.3.1) - - zustand@5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): - optionalDependencies: - '@types/react': 19.1.13 - react: 19.1.1 - use-sync-external-store: 1.4.0(react@19.1.1) - - zustand@5.0.8(@types/react@19.1.13)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): - optionalDependencies: - '@types/react': 19.1.13 - react: 19.1.1 - use-sync-external-store: 1.5.0(react@19.1.1) diff --git a/typescript/packages/x402-axios/src/index.test.ts b/typescript/packages/x402-axios/src/index.test.ts index 0d799ac7c3..9cda6736a5 100644 --- a/typescript/packages/x402-axios/src/index.test.ts +++ b/typescript/packages/x402-axios/src/index.test.ts @@ -228,147 +228,6 @@ describe("withPaymentInterceptor()", () => { }); }); -describe("withPaymentInterceptor() - SVM and MultiNetwork", () => { - beforeEach(() => { - vi.resetModules(); - }); - - it("passes [solana, solana-devnet] for SVM-only signers", async () => { - vi.doMock("x402/types", async () => { - const actual = await vi.importActual("x402/types"); - return { - ...actual, - isEvmSignerWallet: vi.fn().mockReturnValue(false), - isMultiNetworkSigner: vi.fn().mockReturnValue(false), - isSvmSignerWallet: vi.fn().mockReturnValue(true), - }; - }); - - vi.doMock("x402/client", () => ({ - createPaymentHeader: vi.fn().mockResolvedValue("payment-header-value"), - selectPaymentRequirements: vi.fn((reqs: PaymentRequirements[]) => reqs[0]), - })); - - const { withPaymentInterceptor } = await import("./index"); - const { selectPaymentRequirements } = await import("x402/client"); - - const mockAxiosClient: AxiosInstance = { - interceptors: { response: { use: vi.fn() } }, - request: vi.fn().mockResolvedValue({ data: "success" } as AxiosResponse), - } as unknown as AxiosInstance; - - // SVM-like signer (shape is irrelevant due to mocked guards) - const svmWallet = {} as unknown as object; - - withPaymentInterceptor(mockAxiosClient, svmWallet as Signer); - const handler = (mockAxiosClient.interceptors.response.use as ReturnType).mock - .calls[0][1]; - - // Local validPaymentRequirements for this suite - const localValidPaymentRequirements: PaymentRequirements[] = [ - { - scheme: "exact", - network: "solana", - maxAmountRequired: "1000000", - resource: "https://api.example.com/resource", - description: "Test payment", - mimeType: "application/json", - payTo: "11111111111111111111111111111111", - maxTimeoutSeconds: 300, - asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", - }, - ]; - - const error = new AxiosError( - "Error", - "ERROR", - { headers: new AxiosHeaders() } as InternalAxiosRequestConfig, - {}, - { - status: 402, - statusText: "Payment Required", - data: { accepts: [{ ...localValidPaymentRequirements[0] }], x402Version: 1 }, - headers: {}, - config: { headers: new AxiosHeaders() } as InternalAxiosRequestConfig, - }, - ); - - await handler(error); - - expect(selectPaymentRequirements).toHaveBeenCalledWith( - expect.any(Array), - ["solana", "solana-devnet"], - "exact", - ); - }); - - // TODO: this test should be updated once support is added for multi-network signers in selectPaymentRequirements - it("passes undefined for MultiNetwork signers", async () => { - vi.doMock("x402/types", async () => { - const actual = await vi.importActual("x402/types"); - return { - ...actual, - isEvmSignerWallet: vi.fn().mockReturnValue(false), - isSvmSignerWallet: vi.fn().mockReturnValue(false), - isMultiNetworkSigner: vi.fn().mockReturnValue(true), - }; - }); - - vi.doMock("x402/client", () => ({ - createPaymentHeader: vi.fn().mockResolvedValue("payment-header-value"), - selectPaymentRequirements: vi.fn((reqs: PaymentRequirements[]) => reqs[0]), - })); - - const { withPaymentInterceptor } = await import("./index"); - const { selectPaymentRequirements } = await import("x402/client"); - - const mockAxiosClient: AxiosInstance = { - interceptors: { response: { use: vi.fn() } }, - request: vi.fn().mockResolvedValue({ data: "success" } as AxiosResponse), - } as unknown as AxiosInstance; - - // MultiNetwork-like signer - const multiWallet = { evm: {}, svm: {} } as MultiNetworkSigner; - - withPaymentInterceptor(mockAxiosClient, multiWallet); - const handler = (mockAxiosClient.interceptors.response.use as ReturnType).mock - .calls[0][1]; - - // Local validPaymentRequirements for this suite - const localValidPaymentRequirements: PaymentRequirements[] = [ - { - scheme: "exact", - network: "base", - maxAmountRequired: "1000000", - resource: "https://api.example.com/resource", - description: "Test payment", - mimeType: "application/json", - payTo: "0x1234567890123456789012345678901234567890", - maxTimeoutSeconds: 300, - asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", - }, - ]; - - const error = new AxiosError( - "Error", - "ERROR", - { headers: new AxiosHeaders() } as InternalAxiosRequestConfig, - {}, - { - status: 402, - statusText: "Payment Required", - data: { accepts: [{ ...localValidPaymentRequirements[0] }], x402Version: 1 }, - headers: {}, - config: { headers: new AxiosHeaders() } as InternalAxiosRequestConfig, - }, - ); - - await handler(error); - - expect(selectPaymentRequirements).toHaveBeenCalledWith(expect.any(Array), undefined, "exact"); - }); -}); - describe("withDeferredPaymentInterceptor", () => { let mockAxiosClient: AxiosInstance; let mockWalletClient: typeof evm.SignerWallet; @@ -533,3 +392,144 @@ describe("withDeferredPaymentInterceptor", () => { await expect(responseInterceptor(error)).rejects.toBe(paymentError); }); }); + +describe("withPaymentInterceptor() - SVM and MultiNetwork", () => { + beforeEach(() => { + vi.resetModules(); + }); + + it("passes [solana, solana-devnet] for SVM-only signers", async () => { + vi.doMock("x402/types", async () => { + const actual = await vi.importActual("x402/types"); + return { + ...actual, + isEvmSignerWallet: vi.fn().mockReturnValue(false), + isMultiNetworkSigner: vi.fn().mockReturnValue(false), + isSvmSignerWallet: vi.fn().mockReturnValue(true), + }; + }); + + vi.doMock("x402/client", () => ({ + createPaymentHeader: vi.fn().mockResolvedValue("payment-header-value"), + selectPaymentRequirements: vi.fn((reqs: PaymentRequirements[]) => reqs[0]), + })); + + const { withPaymentInterceptor } = await import("./index"); + const { selectPaymentRequirements } = await import("x402/client"); + + const mockAxiosClient: AxiosInstance = { + interceptors: { response: { use: vi.fn() } }, + request: vi.fn().mockResolvedValue({ data: "success" } as AxiosResponse), + } as unknown as AxiosInstance; + + // SVM-like signer (shape is irrelevant due to mocked guards) + const svmWallet = {} as unknown as object; + + withPaymentInterceptor(mockAxiosClient, svmWallet as Signer); + const handler = (mockAxiosClient.interceptors.response.use as ReturnType).mock + .calls[0][1]; + + // Local validPaymentRequirements for this suite + const localValidPaymentRequirements: PaymentRequirements[] = [ + { + scheme: "exact", + network: "solana", + maxAmountRequired: "1000000", + resource: "https://api.example.com/resource", + description: "Test payment", + mimeType: "application/json", + payTo: "11111111111111111111111111111111", + maxTimeoutSeconds: 300, + asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + }, + ]; + + const error = new AxiosError( + "Error", + "ERROR", + { headers: new AxiosHeaders() } as InternalAxiosRequestConfig, + {}, + { + status: 402, + statusText: "Payment Required", + data: { accepts: [{ ...localValidPaymentRequirements[0] }], x402Version: 1 }, + headers: {}, + config: { headers: new AxiosHeaders() } as InternalAxiosRequestConfig, + }, + ); + + await handler(error); + + expect(selectPaymentRequirements).toHaveBeenCalledWith( + expect.any(Array), + ["solana", "solana-devnet"], + "exact", + ); + }); + + // TODO: this test should be updated once support is added for multi-network signers in selectPaymentRequirements + it("passes undefined for MultiNetwork signers", async () => { + vi.doMock("x402/types", async () => { + const actual = await vi.importActual("x402/types"); + return { + ...actual, + isEvmSignerWallet: vi.fn().mockReturnValue(false), + isSvmSignerWallet: vi.fn().mockReturnValue(false), + isMultiNetworkSigner: vi.fn().mockReturnValue(true), + }; + }); + + vi.doMock("x402/client", () => ({ + createPaymentHeader: vi.fn().mockResolvedValue("payment-header-value"), + selectPaymentRequirements: vi.fn((reqs: PaymentRequirements[]) => reqs[0]), + })); + + const { withPaymentInterceptor } = await import("./index"); + const { selectPaymentRequirements } = await import("x402/client"); + + const mockAxiosClient: AxiosInstance = { + interceptors: { response: { use: vi.fn() } }, + request: vi.fn().mockResolvedValue({ data: "success" } as AxiosResponse), + } as unknown as AxiosInstance; + + // MultiNetwork-like signer + const multiWallet = { evm: {}, svm: {} } as MultiNetworkSigner; + + withPaymentInterceptor(mockAxiosClient, multiWallet); + const handler = (mockAxiosClient.interceptors.response.use as ReturnType).mock + .calls[0][1]; + + // Local validPaymentRequirements for this suite + const localValidPaymentRequirements: PaymentRequirements[] = [ + { + scheme: "exact", + network: "base", + maxAmountRequired: "1000000", + resource: "https://api.example.com/resource", + description: "Test payment", + mimeType: "application/json", + payTo: "0x1234567890123456789012345678901234567890", + maxTimeoutSeconds: 300, + asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + }, + ]; + + const error = new AxiosError( + "Error", + "ERROR", + { headers: new AxiosHeaders() } as InternalAxiosRequestConfig, + {}, + { + status: 402, + statusText: "Payment Required", + data: { accepts: [{ ...localValidPaymentRequirements[0] }], x402Version: 1 }, + headers: {}, + config: { headers: new AxiosHeaders() } as InternalAxiosRequestConfig, + }, + ); + + await handler(error); + + expect(selectPaymentRequirements).toHaveBeenCalledWith(expect.any(Array), undefined, "exact"); + }); +}); diff --git a/typescript/packages/x402-axios/src/index.ts b/typescript/packages/x402-axios/src/index.ts index 17fd3110e7..ee9cfc0fa3 100644 --- a/typescript/packages/x402-axios/src/index.ts +++ b/typescript/packages/x402-axios/src/index.ts @@ -20,11 +20,6 @@ import { PaymentRequirementsSchema, Wallet, } from "x402/types"; -import { - createPaymentHeader, - PaymentRequirementsSelector, - selectPaymentRequirements, -} from "x402/client"; /** * Enables the payment of APIs using the x402 payment protocol. @@ -87,7 +82,11 @@ export function withPaymentInterceptor( ? (["solana", "solana-devnet"] as Network[]) : undefined; - const selectedPaymentRequirements = paymentRequirementsSelector(parsed, network, EXACT_SCHEME); + const selectedPaymentRequirements = paymentRequirementsSelector( + parsed, + network, + EXACT_SCHEME, + ); const paymentHeader = await createPaymentHeader( walletClient, x402Version, @@ -182,11 +181,15 @@ export function withDeferredPaymentInterceptor( }; const parsed = accepts.map(x => PaymentRequirementsSchema.parse(x)); - const chainId = evm.isSignerWallet(walletClient) ? walletClient.chain?.id : undefined; + const network = isMultiNetworkSigner(walletClient) + ? undefined + : evm.isSignerWallet(walletClient as typeof evm.EvmSigner) + ? ChainIdToNetwork[(walletClient as typeof evm.EvmSigner).chain?.id] + : undefined; const selectedPaymentRequirements = paymentRequirementsSelector( parsed, - chainId ? ChainIdToNetwork[chainId] : undefined, + network, DEFERRRED_SCHEME, ); const selectedDeferredPaymentRequirements = DeferredPaymentRequirementsSchema.parse( diff --git a/typescript/packages/x402/src/client/selectPaymentRequirements.ts b/typescript/packages/x402/src/client/selectPaymentRequirements.ts index 09dd713454..d4f60e15f0 100644 --- a/typescript/packages/x402/src/client/selectPaymentRequirements.ts +++ b/typescript/packages/x402/src/client/selectPaymentRequirements.ts @@ -1,6 +1,6 @@ import { getUsdcChainConfigForChain } from "../shared/evm"; import { getNetworkId } from "../shared/network"; -import { EXACT_SCHEME, Network, PaymentRequirements } from "../types"; +import { Network, PaymentRequirements, type X402_SCHEMES } from "../types"; /** * Default selector for payment requirements. @@ -15,7 +15,7 @@ import { EXACT_SCHEME, Network, PaymentRequirements } from "../types"; export function selectPaymentRequirements( paymentRequirements: Array, network?: Network | Network[], - scheme?: typeof EXACT_SCHEME, + scheme?: X402_SCHEMES, ): PaymentRequirements { // Sort `base` payment requirements to the front of the list. This is to ensure that base is preferred if available. paymentRequirements.sort((a, b) => { @@ -67,4 +67,4 @@ export function selectPaymentRequirements( * @param scheme - The scheme to check against. If not provided, the scheme will not be checked. * @returns The payment requirement that is the most appropriate for the user. */ -export type PaymentRequirementsSelector = (paymentRequirements: Array, network?: Network | Network[], scheme?: typeof EXACT_SCHEME) => PaymentRequirements; +export type PaymentRequirementsSelector = (paymentRequirements: Array, network?: Network | Network[], scheme?: X402_SCHEMES) => PaymentRequirements; diff --git a/typescript/packages/x402/src/schemes/exact/svm/client.ts b/typescript/packages/x402/src/schemes/exact/svm/client.ts index d0a97f67d8..7e5f81d498 100644 --- a/typescript/packages/x402/src/schemes/exact/svm/client.ts +++ b/typescript/packages/x402/src/schemes/exact/svm/client.ts @@ -199,7 +199,7 @@ async function createAtaInstructionOrUndefined( if (!feePayer) { throw new Error( "feePayer is required in paymentRequirements.extra in order to set the " + - "facilitator as the fee payer for the create associated token account instruction", + "facilitator as the fee payer for the create associated token account instruction", ); } From 3f5f15ad3e07d95d50e91be4f2850345c2ab3fc3 Mon Sep 17 00:00:00 2001 From: Pablo Carranza Velez Date: Fri, 15 Aug 2025 22:32:20 -0300 Subject: [PATCH 070/116] feat: add deferred scheme specifications - Add deferred scheme abstract definition - Add EVM-specific implementation details - Add voucher data structure specification - Define EIP-712 typed data structures for deferred payments This scheme enables asynchronous payment collection where buyers sign payment vouchers that sellers can later redeem on-chain. --- specs/schemes/deferred/scheme_deferred.md | 15 ++ specs/schemes/deferred/scheme_deferred_evm.md | 144 ++++++++++++++++++ specs/voucher.md | 53 +++++++ 3 files changed, 212 insertions(+) create mode 100644 specs/schemes/deferred/scheme_deferred.md create mode 100644 specs/schemes/deferred/scheme_deferred_evm.md create mode 100644 specs/voucher.md diff --git a/specs/schemes/deferred/scheme_deferred.md b/specs/schemes/deferred/scheme_deferred.md new file mode 100644 index 0000000000..7cfaeb5ecb --- /dev/null +++ b/specs/schemes/deferred/scheme_deferred.md @@ -0,0 +1,15 @@ +# Scheme: `deferred` + +## Summary + +`deferred` is a scheme designed to support micro-payments between AI agents or automated clients. Unlike the `exact` scheme, which requires a payment to be executed immediately and fully on-chain, `deferred` allows clients to issue signed vouchers (IOUs) off-chain, which can later be aggregated and redeemed by the seller. This scheme enables payments smaller than the minimum feasible on-chain transaction cost. + +## Example Use Cases + +- An LLM paying to use a tool + +## Related Schemes + +- **`deferred_paymaster`**: Extension that uses an intermediary Paymaster service to improve UX by eliminating buyer escrow management + +## Appendix \ No newline at end of file diff --git a/specs/schemes/deferred/scheme_deferred_evm.md b/specs/schemes/deferred/scheme_deferred_evm.md new file mode 100644 index 0000000000..d1adfd5c1b --- /dev/null +++ b/specs/schemes/deferred/scheme_deferred_evm.md @@ -0,0 +1,144 @@ +# Scheme: `deferred` on `EVM` + +## Summary + +The `deferred` scheme on EVM chains uses `EIP-712` signed vouchers to represent payment commitments from a buyer to a seller. Before issuing vouchers, the buyer deposits funds—denominated in a specific `ERC-20` token—into an on-chain escrow earmarked for the seller. Each voucher authorizes a payment against that escrow balance, and explicitly specifies the asset being used. +Sellers can collect and aggregate these signed messages over time, choosing when to redeem them on-chain and settling the total amount in a single transaction. +This design enables efficient, asset-flexible micropayments without incurring prohibitive gas costs for every interaction. + +## `X-Payment` header payload + +The `payload` field of the `X-PAYMENT` header must contain the following fields: + +- `signature`: The signature of the `EIP-712` voucher. +- `voucher`: parameters required to reconstruct the signed message for the operation. + +### Voucher Fields + +- `id`: Unique identifier for the voucher (bytes32) +- `buyer`: Address of the payment initiator (address) +- `seller`: Address of the payment recipient (address) +- `valueAggregate`: Total outstanding amount in the voucher, monotonically increasing (uint256) +- `asset`: ERC-20 token address (address) +- `timestamp`: Last aggregation timestamp (uint64) +- `nonce`: Incremented with each aggregation (uint256) +- `escrow`: Address of the escrow contract (address) +- `chainId`: Network chain ID (uint256) +- `expiry`: Expiration timestamp after which voucher cannot be collected (uint64) + +Example: + +```json +{ + "signature": "0x3a2f7e3b6c1d8e9c0f64f8724e5cfb8bfe9a3cdb1ad6e4a876f7d418e47e96b11a23346a1b0e60c8d3a4c4fd0150a244ab4b0e6d6c5fa4103f8fa8fd2870a3c81b", + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "2000000000000000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1740673000, + "nonce": 3, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1740759400 + } +} +``` + +Full `X-PAYMENT` header: + +```json +{ + "x402Version": 1, + "scheme": "deferred", + "network": "base-sepolia", + "payload": { + "signature": "0x3a2f7e3b6c1d8e9c0f64f8724e5cfb8bfe9a3cdb1ad6e4a876f7d418e47e96b11a23346a1b0e60c8d3a4c4fd0150a244ab4b0e6d6c5fa4103f8fa8fd2870a3c81b", + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "2000000000000000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1740673000, + "nonce": 3, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1740759400 + } + } +} +``` + +## `paymentRequirements` extra object + +The `extra` object in the "Payment Required Response" should contain the following fields: +- If this is a new voucher being created: + - `voucher`: A simplified voucher object with: + - `id`: The voucher id + - `escrow`: The address of the escrow contract +- If an existing voucher is being aggregated: + - `signature`: The signature of the latest voucher corresponding to the given `id` + - `voucher`: The latest voucher corresponding to the given `id` +- Additionally a `type` field to indicate wether it's a new voucher or an aggregation + +Example: + +```json +{ + ... + "extra": { + "type": "new", + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + } + } +} + +{ + ... + "extra": { + "type": "aggregation", + "signature": "0x3a2f7e3b6c1d8e9c0f64f8724e5cfb8bfe9a3cdb1ad6e4a876f7d418e47e96b11a23346a1b0e60c8d3a4c4fd0150a244ab4b0e6d6c5fa4103f8fa8fd2870a3c81b", + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "2000000000000000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1740673000, + "nonce": 3, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1740759400 + } + } +} +``` + +## Verification + +Steps to verify a payment for the `deferred` scheme: + +1. Verify the signature is valid +2. Verify the `paymentPayload` matches the requirements set by `paymentRequirements` + - Verify scheme is `"deferred"` + - Verify `paymentPayload.network` matches `paymentRequirements.network` + - Verify `paymentPayload.voucher.valueAggregate` is enough to cover `paymentRequirements.maxAmountRequired` plus previous voucher value aggregate if it's an aggregate voucher + - Verify `paymentRequirements.payTo` matches `paymentPayload.voucher.seller` + - Verify `paymentPayload.voucher.asset` matches `paymentRequirements.asset` + - Validates the `paymentPayload.voucher.chainId` matches the chain specified by `paymentRequirements.network` + - Validates the `paymentPayload.voucher.expiry` and `paymentPayload.voucher.timestamp` dates make sense +3. Verify the `buyer` has enough of the `asset` (ERC20 token) in the escrow to cover the valueAggregate in the `payload.voucher` +4. Verify the valueAggregate in the `payload.voucher`, minus any payments already made for its `id`, is enough to cover `paymentRequirements.maxAmountRequired` +5. Verify the voucher has not expired by checking that the current timestamp is less than or equal to `expiry` +6. Verify `chainId` matches the chain id for the `paymentPayload.network` +7. (Optional, but recommended) Simulate the voucher collection to ensure the transaction would succeed + +## Settlement + +Settlement is performed via the facilitator calling the `collect` function on the `deferred` escrow contract with the `payload.signature` and `payload.voucher` parameters from the `X-PAYMENT` header. + +Multiple vouchers may be collected in a single transaction, using the `collectMany` function. diff --git a/specs/voucher.md b/specs/voucher.md new file mode 100644 index 0000000000..626303805a --- /dev/null +++ b/specs/voucher.md @@ -0,0 +1,53 @@ +# voucher specification + +## Specification +An `EIP-712` signed message with the following data: + +| Property | Type | Description | +|------------|----------|-------------| +| `id` | `bytes32` | A unique identifier for an ongoing buyer-seller aggregation relationship. Used to prevent vouchers from being double claimed, and can also support simultaneous aggregations for parallel requests. | +| `buyer` | `address` | Address of the payment initiator, i.e., the buyer agent. | +| `seller` | `address` | Address of the payment recipient, i.e., the seller agent. | +| `valueAggregate` | `uint256` | The total outstanding amount owed. This value represents the amount the seller can collect on-chain from the buyer. It should be monotonically increasing with each voucher aggregation. | +| `asset` | `address` | The ERC-20 token address representing the currency used in the voucher. | +| `timestamp`| `uint64` | Timestamp when this voucher was last aggregated. | +| `nonce` | `uint256` | A nonce for the voucher. Incremented each time the voucher is aggregated. | +| `escrow` | `address` | Address of the escrow contract where the voucher can be collected at. | +| `chainId` | `uint64` | Chain id of the network where the voucher can be collected at. | + +## Voucher Verification + +### Smart contracts +- Verify the signature is valid +- Verify `chainId` matches the network chain id +- Verify `buyer` balance of `asset` is enough to cover `valueAggregate` in voucher +- Verify the `id` has not been used, or if it has, that the new balance is greater than what was already paid (in which case we'll pay the difference) + +### Facilitator +1. Verify the signature is valid +2. Verify the `paymentPayload` matches the requirements set by `paymentRequirements` + - Verify scheme is `"deferred"` + - Verify `paymentPayload.network` matches `paymentRequirements.network` + - Verify `paymentPayload.voucher.valueAggregate` is enough to cover `paymentRequirements.maxAmountRequired` plus previous voucher value aggregate if it's an aggregate voucher + - Verify `paymentRequirements.payTo` matches `paymentPayload.voucher.seller` + - Verify `paymentPayload.voucher.asset` matches `paymentRequirements.asset` + - Validates the `paymentPayload.voucher.chainId` matches the chain specified by `paymentRequirements.network` + - Validates the `paymentPayload.voucher.expiry` and `paymentPayload.voucher.timestamp` dates make sense +3. Verify the `buyer` has enough of the `asset` (ERC20 token) in the escrow to cover the valueAggregate in the `payload.voucher` +4. Verify `id` has not been already collected in the escrow, or if it has, that the new balance is greater than what was already paid (in which case we'll pay the difference) +5. (Optional, but recommended) Simulate the voucher collection to ensure the transaction would succeed + +### Gateway +- If a voucher with the same `id` already exists, get the latest using `timestamp` and: + - Verify `nonce` equals the previous `nonce + 1` + - Verify `valueAggregate` is equal to the previous `valueAggregate + paymentRequirements.maxAmountRequired` + - Verify `timestamp` is greater than the previous `timestamp` + - Verify `buyer`, `seller`, `asset`, `escrow` and `chainId` all match the previous voucher values + +### Seller +- Performs no verification, trusts the gateway + +### Buyer +- When aggregating a voucher: + - Verify the signature is valid + - Verify the `seller`, `asset` and `chainId` in the previous voucher match the payment requirements From ad8bb6b5c2ec989fdee78fae41f38401eacfc593 Mon Sep 17 00:00:00 2001 From: Pablo Carranza Velez Date: Sun, 17 Aug 2025 23:23:51 -0300 Subject: [PATCH 071/116] refactor: consolidate voucher spec and merge gateway into facilitator - Merge unique verification details from voucher.md into main EVM spec - Consolidate gateway role into facilitator for simplified architecture - Add component-specific verification sections (facilitator, smart contract, seller, buyer) - Remove redundant voucher.md file to avoid duplication --- specs/schemes/deferred/scheme_deferred_evm.md | 52 ++++++++++++++---- specs/voucher.md | 53 ------------------- 2 files changed, 41 insertions(+), 64 deletions(-) delete mode 100644 specs/voucher.md diff --git a/specs/schemes/deferred/scheme_deferred_evm.md b/specs/schemes/deferred/scheme_deferred_evm.md index d1adfd5c1b..2bf3d3c8aa 100644 --- a/specs/schemes/deferred/scheme_deferred_evm.md +++ b/specs/schemes/deferred/scheme_deferred_evm.md @@ -120,22 +120,52 @@ Example: ## Verification -Steps to verify a payment for the `deferred` scheme: +### Facilitator Verification -1. Verify the signature is valid -2. Verify the `paymentPayload` matches the requirements set by `paymentRequirements` +The facilitator performs comprehensive verification when receiving a deferred payment: + +1. **Signature validation**: Verify the EIP-712 signature is valid +2. **Payment requirements matching**: - Verify scheme is `"deferred"` - Verify `paymentPayload.network` matches `paymentRequirements.network` - - Verify `paymentPayload.voucher.valueAggregate` is enough to cover `paymentRequirements.maxAmountRequired` plus previous voucher value aggregate if it's an aggregate voucher - Verify `paymentRequirements.payTo` matches `paymentPayload.voucher.seller` - Verify `paymentPayload.voucher.asset` matches `paymentRequirements.asset` - - Validates the `paymentPayload.voucher.chainId` matches the chain specified by `paymentRequirements.network` - - Validates the `paymentPayload.voucher.expiry` and `paymentPayload.voucher.timestamp` dates make sense -3. Verify the `buyer` has enough of the `asset` (ERC20 token) in the escrow to cover the valueAggregate in the `payload.voucher` -4. Verify the valueAggregate in the `payload.voucher`, minus any payments already made for its `id`, is enough to cover `paymentRequirements.maxAmountRequired` -5. Verify the voucher has not expired by checking that the current timestamp is less than or equal to `expiry` -6. Verify `chainId` matches the chain id for the `paymentPayload.network` -7. (Optional, but recommended) Simulate the voucher collection to ensure the transaction would succeed + - Verify `paymentPayload.voucher.chainId` matches the chain specified by `paymentRequirements.network` +3. **Voucher aggregation validation** (if aggregating an existing voucher): + - Verify `nonce` equals the previous `nonce + 1` + - Verify `valueAggregate` is equal to the previous `valueAggregate + paymentRequirements.maxAmountRequired` + - Verify `timestamp` is greater than the previous `timestamp` + - Verify `buyer`, `seller`, `asset`, `escrow` and `chainId` all match the previous voucher values +4. **Amount validation**: + - Verify `paymentPayload.voucher.valueAggregate` is enough to cover `paymentRequirements.maxAmountRequired` plus previous voucher value aggregate if it's an aggregate voucher +5. **Escrow balance check**: + - Verify the `buyer` has enough of the `asset` (ERC20 token) in the escrow to cover the valueAggregate in the `payload.voucher` + - Verify `id` has not been already collected in the escrow, or if it has, that the new balance is greater than what was already paid (in which case the difference will be paid) +6. **Expiry validation**: + - Verify the voucher has not expired by checking that the current timestamp is less than or equal to `expiry` + - Verify `paymentPayload.voucher.expiry` and `paymentPayload.voucher.timestamp` dates make sense +7. **Transaction simulation** (optional but recommended): + - Simulate the voucher collection to ensure the transaction would succeed on-chain + +### Smart Contract Verification + +When vouchers are collected on-chain, the escrow smart contract verifies: + +1. Signature validity for the EIP-712 typed data +2. `chainId` matches the network chain id +3. `buyer` balance of `asset` is sufficient to cover `valueAggregate` in voucher +4. The `id` has not been used, or if it has, that the new balance is greater than what was already paid (paying only the difference) + +### Seller Verification + +Sellers trust the facilitator's verification and do not perform additional checks when receiving vouchers. + +### Buyer Verification + +When aggregating a voucher, buyers should: + +1. Verify the signature is valid +2. Verify the `seller`, `asset` and `chainId` in the previous voucher match the payment requirements ## Settlement diff --git a/specs/voucher.md b/specs/voucher.md deleted file mode 100644 index 626303805a..0000000000 --- a/specs/voucher.md +++ /dev/null @@ -1,53 +0,0 @@ -# voucher specification - -## Specification -An `EIP-712` signed message with the following data: - -| Property | Type | Description | -|------------|----------|-------------| -| `id` | `bytes32` | A unique identifier for an ongoing buyer-seller aggregation relationship. Used to prevent vouchers from being double claimed, and can also support simultaneous aggregations for parallel requests. | -| `buyer` | `address` | Address of the payment initiator, i.e., the buyer agent. | -| `seller` | `address` | Address of the payment recipient, i.e., the seller agent. | -| `valueAggregate` | `uint256` | The total outstanding amount owed. This value represents the amount the seller can collect on-chain from the buyer. It should be monotonically increasing with each voucher aggregation. | -| `asset` | `address` | The ERC-20 token address representing the currency used in the voucher. | -| `timestamp`| `uint64` | Timestamp when this voucher was last aggregated. | -| `nonce` | `uint256` | A nonce for the voucher. Incremented each time the voucher is aggregated. | -| `escrow` | `address` | Address of the escrow contract where the voucher can be collected at. | -| `chainId` | `uint64` | Chain id of the network where the voucher can be collected at. | - -## Voucher Verification - -### Smart contracts -- Verify the signature is valid -- Verify `chainId` matches the network chain id -- Verify `buyer` balance of `asset` is enough to cover `valueAggregate` in voucher -- Verify the `id` has not been used, or if it has, that the new balance is greater than what was already paid (in which case we'll pay the difference) - -### Facilitator -1. Verify the signature is valid -2. Verify the `paymentPayload` matches the requirements set by `paymentRequirements` - - Verify scheme is `"deferred"` - - Verify `paymentPayload.network` matches `paymentRequirements.network` - - Verify `paymentPayload.voucher.valueAggregate` is enough to cover `paymentRequirements.maxAmountRequired` plus previous voucher value aggregate if it's an aggregate voucher - - Verify `paymentRequirements.payTo` matches `paymentPayload.voucher.seller` - - Verify `paymentPayload.voucher.asset` matches `paymentRequirements.asset` - - Validates the `paymentPayload.voucher.chainId` matches the chain specified by `paymentRequirements.network` - - Validates the `paymentPayload.voucher.expiry` and `paymentPayload.voucher.timestamp` dates make sense -3. Verify the `buyer` has enough of the `asset` (ERC20 token) in the escrow to cover the valueAggregate in the `payload.voucher` -4. Verify `id` has not been already collected in the escrow, or if it has, that the new balance is greater than what was already paid (in which case we'll pay the difference) -5. (Optional, but recommended) Simulate the voucher collection to ensure the transaction would succeed - -### Gateway -- If a voucher with the same `id` already exists, get the latest using `timestamp` and: - - Verify `nonce` equals the previous `nonce + 1` - - Verify `valueAggregate` is equal to the previous `valueAggregate + paymentRequirements.maxAmountRequired` - - Verify `timestamp` is greater than the previous `timestamp` - - Verify `buyer`, `seller`, `asset`, `escrow` and `chainId` all match the previous voucher values - -### Seller -- Performs no verification, trusts the gateway - -### Buyer -- When aggregating a voucher: - - Verify the signature is valid - - Verify the `seller`, `asset` and `chainId` in the previous voucher match the payment requirements From 3ba04a252789085e038e3811a6771c569b919ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 26 Sep 2025 09:18:39 -0300 Subject: [PATCH 072/116] fix: ensure deferred scheme supports smart account signing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402/src/schemes/deferred/evm/sign.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts index f2d2b5c5fc..a3d9c4ec9c 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts @@ -1,12 +1,14 @@ -import { Address, Chain, getAddress, Hex, LocalAccount, Transport, verifyTypedData } from "viem"; +import { Address, Chain, getAddress, Hex, LocalAccount, Transport } from "viem"; import { typedDataTypes, isAccount, isSignerWallet, SignerWallet, deferredVoucherPrimaryType, + createConnectedClient, } from "../../../types/shared/evm"; import { DeferredEvmPayloadVoucher } from "../../../types/verify/schemes/deferred"; +import { getNetworkName } from "../../../shared"; /** * Signs a voucher @@ -84,8 +86,8 @@ export async function verifyVoucher( message: voucher, }; - // TODO: use client.verifyTypedData to support smart accounts - return await verifyTypedData({ + const client = createConnectedClient(getNetworkName(voucher.chainId)); + return await client.verifyTypedData({ address: signer, ...voucherTypedData, signature: signature as Hex, From c8ad37fefa3ff8f1dd74c8ab2bc94abf55aef6e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 29 Sep 2025 14:47:03 -0300 Subject: [PATCH 073/116] docs: add deferred specification documents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- specs/schemes/deferred/scheme_deferred.md | 7 +- specs/schemes/deferred/scheme_deferred_evm.md | 64 ++++-- .../scheme_deferred_evm_escrow_contract.md | 215 ++++++++++++++++++ .../scheme_deferred_evm_voucher_store.md | 168 ++++++++++++++ 4 files changed, 431 insertions(+), 23 deletions(-) create mode 100644 specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md create mode 100644 specs/schemes/deferred/scheme_deferred_evm_voucher_store.md diff --git a/specs/schemes/deferred/scheme_deferred.md b/specs/schemes/deferred/scheme_deferred.md index 7cfaeb5ecb..ad3451d54e 100644 --- a/specs/schemes/deferred/scheme_deferred.md +++ b/specs/schemes/deferred/scheme_deferred.md @@ -4,12 +4,11 @@ `deferred` is a scheme designed to support micro-payments between AI agents or automated clients. Unlike the `exact` scheme, which requires a payment to be executed immediately and fully on-chain, `deferred` allows clients to issue signed vouchers (IOUs) off-chain, which can later be aggregated and redeemed by the seller. This scheme enables payments smaller than the minimum feasible on-chain transaction cost. +`deferred` payment scheme requires the seller to store and manage the buyer's vouchers until their eventual on chain settlement. To simplify their setup sellers might choose to offload this task to trusted third parties providing these services, i.e facilitators. + ## Example Use Cases - An LLM paying to use a tool - -## Related Schemes - -- **`deferred_paymaster`**: Extension that uses an intermediary Paymaster service to improve UX by eliminating buyer escrow management +- Any case where payments are smaller than on-chain settlement costs ## Appendix \ No newline at end of file diff --git a/specs/schemes/deferred/scheme_deferred_evm.md b/specs/schemes/deferred/scheme_deferred_evm.md index 2bf3d3c8aa..d14bd886e5 100644 --- a/specs/schemes/deferred/scheme_deferred_evm.md +++ b/specs/schemes/deferred/scheme_deferred_evm.md @@ -2,7 +2,7 @@ ## Summary -The `deferred` scheme on EVM chains uses `EIP-712` signed vouchers to represent payment commitments from a buyer to a seller. Before issuing vouchers, the buyer deposits funds—denominated in a specific `ERC-20` token—into an on-chain escrow earmarked for the seller. Each voucher authorizes a payment against that escrow balance, and explicitly specifies the asset being used. +The `deferred` scheme on EVM chains uses `EIP-712` signed vouchers to represent payment commitments from a buyer to a seller. Before issuing vouchers, the buyer deposits funds—denominated in a specific `ERC-20` token—into an on-chain escrow earmarked for the seller. Each voucher authorizes a payment against that escrow balance, and explicitly specifies the asset being used. Sellers can collect and aggregate these signed messages over time, choosing when to redeem them on-chain and settling the total amount in a single transaction. This design enables efficient, asset-flexible micropayments without incurring prohibitive gas costs for every interaction. @@ -120,9 +120,7 @@ Example: ## Verification -### Facilitator Verification - -The facilitator performs comprehensive verification when receiving a deferred payment: +The following steps are required to verify a deferred payment: 1. **Signature validation**: Verify the EIP-712 signature is valid 2. **Payment requirements matching**: @@ -147,28 +145,56 @@ The facilitator performs comprehensive verification when receiving a deferred pa 7. **Transaction simulation** (optional but recommended): - Simulate the voucher collection to ensure the transaction would succeed on-chain -### Smart Contract Verification +## Settlement -When vouchers are collected on-chain, the escrow smart contract verifies: +Settlement is performed via the facilitator calling the `collect` function on the escrow contract with the `payload.signature` and `payload.voucher` parameters from the `X-PAYMENT` header. This can be initiated by buyer's request or the facilitator holding the vouchers could trigger automatic settlement based on pre-agreed conditions. -1. Signature validity for the EIP-712 typed data -2. `chainId` matches the network chain id -3. `buyer` balance of `asset` is sufficient to cover `valueAggregate` in voucher -4. The `id` has not been used, or if it has, that the new balance is greater than what was already paid (paying only the difference) +Multiple vouchers may be collected in a single transaction, using the `collectMany` function. -### Seller Verification +## Appendix -Sellers trust the facilitator's verification and do not perform additional checks when receiving vouchers. +### `X-Payment-Buyer` header -### Buyer Verification +The `X-PAYMENT-BUYER` header allows buyers to notify sellers about their identity before signing any voucher or message. This enables sellers to determine whether to request a new voucher or check their voucher store for existing vouchers for further aggregation. It's important to note this header requires no proof of identity, the seller assumes the buyer is who it claims to be. This is not a problem however since the payment flow will later require valid signatures which an impostor wont be able to forge. -When aggregating a voucher, buyers should: +The header contains the buyer's EVM address as a simple string: -1. Verify the signature is valid -2. Verify the `seller`, `asset` and `chainId` in the previous voucher match the payment requirements +``` +X-PAYMENT-BUYER: 0x209693Bc6afc0C5328bA36FaF03C514EF312287C +``` -## Settlement +The buyer needs to add this header when initially requesting access to a resource. Failing to provide the header will result in new vouchers being created on each interaction, defeating the purpose of the `deferred` scheme. -Settlement is performed via the facilitator calling the `collect` function on the `deferred` escrow contract with the `payload.signature` and `payload.voucher` parameters from the `X-PAYMENT` header. +Example 402 response with an existing voucher: +```json +{ + "x402Version": 1, + "accepts": [{ + "scheme": "deferred", + "network": "base-sepolia", + "maxAmountRequired": "1000000", + "payTo": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "extra": { + "type": "aggregation", + "signature": "0x3a2f7e3b...", + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "5000000", + "nonce": 2, + // ... other voucher fields + } + } + }] +} +``` -Multiple vouchers may be collected in a single transaction, using the `collectMany` function. +### Voucher store specification + +Facilitators supporting the `deferred` scheme should offer a persistent voucher store for sellers. For a complete specification see [Voucher Store specification](./voucher_store.md). + +### Escrow contract specification + +The full specification for the deferred escrow contract can be found here: [DeferredPaymentEscrow specification](./scheme_deferred_evm_escrow_contract.md) \ No newline at end of file diff --git a/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md b/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md new file mode 100644 index 0000000000..e639f6a219 --- /dev/null +++ b/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md @@ -0,0 +1,215 @@ + +# DeferredPaymentEscrow Contract Specification + +## Summary + +The `DeferredPaymentEscrow` contract enables micropayments using an escrow-based voucher system. Buyers deposit ERC-20 tokens into escrow accounts for specific sellers, then issue off-chain EIP-712 signed vouchers that sellers can redeem against those deposits. This approach allows for efficient aggregation of many small payments before on-chain settlement, while maintaining security through cryptographic signatures and time-bounded withdrawals. + +The contract is designed for scenarios where payments are frequent but small (micropayments), making individual on-chain transactions economically inefficient. It provides strong guarantees to both parties: buyers retain control over their deposited funds through a thawing mechanism, while sellers can collect payments immediately when vouchers are presented. + +## Contract Overview + +The contract manages deposits, withdrawals, and voucher redemption: + +- **Deposits**: Buyers deposit ERC-20 tokens for specific sellers +- **Vouchers**: Off-chain signed promises to pay that aggregate over time +- **Collection**: Sellers redeem vouchers against escrow balances +- **Withdrawal**: Buyers can withdraw unused funds after a thawing period +- **Authorization**: EIP-712 signed operations for gasless interactions (designed for x402 Facilitators to be able to abstract escrow management actions from buyers) + +## Data Structures + +### EscrowAccount +```solidity +struct EscrowAccount { + uint256 balance; // Total deposited balance (includes thawing amount) + uint256 thawingAmount; // Amount currently thawing for withdrawal (subset of balance) + uint64 thawEndTime; // When thawing completes +} +``` + +**Important**: The `balance` field represents the total amount of tokens held in the escrow account, which includes any amount currently thawing. The `thawingAmount` is a subset of the `balance` that has been marked for withdrawal after the thawing period. Available funds for new thawing operations = `balance - thawingAmount`. + +### Voucher +```solidity +struct Voucher { + bytes32 id; // Unique identifier per buyer-seller pair + address buyer; // Payment initiator + address seller; // Payment recipient + uint256 valueAggregate; // Total accumulated amount (monotonically increasing) + address asset; // ERC-20 token address + uint64 timestamp; // Last aggregation timestamp + uint256 nonce; // Incremented with each aggregation + address escrow; // This contract's address + uint256 chainId; // Network chain ID + uint64 expiry; // Expiration timestamp +} +``` + +## Account Structure + +The contract uses a triple-nested mapping to organize escrow accounts: +``` +buyer → seller → asset → EscrowAccount +``` + +This structure ensures: +- Each buyer-seller pair has independent accounts +- Different assets (tokens) are tracked separately +- Clean separation of concerns between relationships + +## Payment Flow + +### 1. Deposit Phase +``` +Buyer → deposit(seller, asset, amount) → Escrow Contract + +OR + +Facilitator → depositWithAuthorization(auth, signature) → Escrow Contract +``` + +### 2. Service & Voucher Phase +``` +Buyer ↔ Seller (off-chain interactions) +Buyer → signs Voucher(id, valueAggregate, ...) → Seller +``` + +### 3. Collection Phase +``` +Seller → collect(voucher, signature) → Escrow Contract +Escrow Contract → transfer(asset, amount) → Seller +``` + +### 4. Withdrawal Phase (if needed) +``` +Buyer → thaw(seller, asset, amount) → Escrow Contract +[wait THAWING_PERIOD] +Buyer → withdraw(seller, asset) → Escrow Contract +``` + +## Verification + +To verify a payment in the `deferred` scheme: + +1. **Signature Validation**: Verify the voucher signature using EIP-712 and ERC-1271 +2. **Contract Verification**: Ensure `voucher.escrow` matches the expected contract address +3. **Chain Verification**: Ensure `voucher.chainId` matches the current network +4. **Expiry Check**: Verify `block.timestamp <= voucher.expiry` +5. **Balance Check**: Verify escrow account has sufficient balance for collection +6. **Aggregation Validation**: Ensure `voucher.valueAggregate >= previous_collections` + +## Settlement + +Settlement occurs when sellers call the `collect` function: + +1. **Validation**: Contract validates voucher parameters and signature +2. **Amount Calculation**: Determines collectable amount based on: + - Total voucher value (`valueAggregate`) + - Previously collected amounts for this voucher ID + - Available balance in escrow account +3. **State Updates**: Records new collected amount and updates escrow balance +4. **Transfer**: Sends tokens directly to seller +5. **Events**: Emits collection events for off-chain tracking + +### Partial Collection + +If escrow balance is insufficient for the full voucher amount: +- Contract collects only the available amount +- Voucher remains valid for future collection of remaining amount +- Prevents voucher failures due to temporary fund shortages + +**Note for Sellers**: Before accepting a voucher off-chain, sellers should verify that the escrow account has sufficient balance to cover the voucher amount. This can be checked using `getOutstandingAndCollectableAmount(voucher)` which returns both the outstanding amount owed and the amount that can actually be collected immediately. + +## Withdrawal Protection + +The thawing mechanism protects sellers from sudden fund withdrawals: + +1. **Thaw Initiation**: Buyer calls `thaw(seller, asset, amount)` (calling `thaw()` multiple times will add to the thawing amount and reset the timer) +2. **Thawing Period**: Set at contract deployment (standard value is 1 day, though other escrow instances can be deployed with different thawing periods if needed) +3. **Seller Collection**: Sellers can still collect from full balance during thawing +4. **Withdrawal**: After thawing period, buyer can withdraw thawed amount +5. **Cancellation**: Buyers can cancel thawing at any time before completion + +## Authorization System + +### Gasless Operations + +The contract supports EIP-712 signed authorizations for gasless operations, designed for x402: + +### Deposit Authorization +Allows x402 Facilitators to execute deposits on behalf of buyers: +```solidity +struct DepositAuthorization { + address buyer; // Who is authorizing + address seller; // Recipient + address asset; // Token to deposit + uint256 amount; // Amount to deposit + bytes32 nonce; // Random bytes32 for replay protection + uint64 expiry; // Authorization expiration +} +``` + +### Flush Authorization +Enables x402 Facilitators to "flush" funds for buyers (withdraws any funds that have completed thawing, then starts thawing any remaining balance): +```solidity +struct FlushAuthorization { + address buyer; // Who is authorizing + address seller; // Specific account to flush + address asset; // Specific asset to flush + bytes32 nonce; // Random bytes32 for replay protection + uint64 expiry; // Authorization expiration +} +``` + +### Flush All Authorization +Allows batch withdrawal from all of a buyer's escrow accounts (performs flush operation on every account): +```solidity +struct FlushAllAuthorization { + address buyer; // Who is authorizing + bytes32 nonce; // Random bytes32 for replay protection + uint64 expiry; // Authorization expiration +} +``` + +## Contract Interface + +### Core Functions + +### Deposits +- `deposit(address seller, address asset, uint256 amount)` - Direct deposit +- `depositTo(address buyer, address seller, address asset, uint256 amount)` - Third-party deposit +- `depositMany(address asset, DepositInput[] deposits)` - Batch deposits +- `depositWithAuthorization(DepositAuthorization auth, bytes signature)` - Gasless deposit + +### Withdrawals +- `thaw(address seller, address asset, uint256 amount)` - Initiate withdrawal +- `cancelThaw(address seller, address asset)` - Cancel ongoing thaw +- `withdraw(address seller, address asset)` - Complete withdrawal +- `flushWithAuthorization(FlushAuthorization auth, bytes signature)` - Gasless specific flush +- `flushAllWithAuthorization(FlushAllAuthorization auth, bytes signature)` - Gasless batch flush + +### Collections +- `collect(Voucher voucher, bytes signature)` - Single voucher redemption +- `collectMany(SignedVoucher[] vouchers)` - Batch voucher redemption + +### View Functions +- `getAccount(address buyer, address seller, address asset)` → `EscrowAccount` - Get escrow account details +- `getVoucherCollected(address buyer, address seller, address asset, bytes32 voucherId)` → `uint256` - Get total amount already collected for this voucher ID +- `getOutstandingAndCollectableAmount(Voucher voucher)` → `(uint256 outstanding, uint256 collectable)` - Returns outstanding amount still owed and amount that can be collected immediately given current escrow balance +- `isVoucherSignatureValid(Voucher voucher, bytes signature)` → `bool` - Validate voucher signature +- `isDepositAuthorizationValid(DepositAuthorization auth, bytes signature)` → `bool` - Validate deposit authorization signature +- `isFlushAuthorizationValid(FlushAuthorization auth, bytes signature)` → `bool` - Validate flush authorization signature +- `isFlushAllAuthorizationValid(FlushAllAuthorization auth, bytes signature)` → `bool` - Validate flush all authorization signature + +### Constants +- `THAWING_PERIOD()` → `uint256` - Withdrawal thawing period (immutable, set at deployment) +- `MAX_THAWING_PERIOD()` → `uint256` - Maximum allowed thawing period (30 days) +- `DOMAIN_SEPARATOR()` → `bytes32` - EIP-712 domain separator + +### Multi-Chain Deployment + +While each contract instance operates on a single chain, the design supports multi-chain deployments: +- Vouchers include `chainId` for chain-specific validation +- Contract will be deployed using Safe Singleton Factory for deterministic addresses across chains +- Cross-chain coordination must be handled at the application layer \ No newline at end of file diff --git a/specs/schemes/deferred/scheme_deferred_evm_voucher_store.md b/specs/schemes/deferred/scheme_deferred_evm_voucher_store.md new file mode 100644 index 0000000000..ff23fb9575 --- /dev/null +++ b/specs/schemes/deferred/scheme_deferred_evm_voucher_store.md @@ -0,0 +1,168 @@ +# Voucher Store Specification + +## Summary + +The Voucher Store is a critical component of the X402 `deferred` payment scheme that manages the persistence and retrieval of signed payment vouchers and their settlement records. It serves as the data layer for sellers and facilitators to track off-chain payment obligations and their eventual on-chain settlements. + +This specification defines the interface and requirements for implementing a voucher store in the deferred EVM payment system, ensuring consistent behavior across different implementations (in-memory, database-backed, etc.). + +## Overview + +The voucher store manages three key concepts: + +1. **Vouchers**: EIP-712 signed payment commitments from buyers to sellers +2. **Voucher Series**: A sequence of vouchers sharing the same ID but with different nonces (representing aggregations) +3. **Collections**: Records of on-chain settlements for vouchers + +## Data Model + +### Voucher Structure + +A voucher contains the following fields: + +| Field | Type | Description | +|-------|------|-------------| +| `id` | bytes32 | Unique identifier for the voucher series | +| `buyer` | address | Address of the payment initiator | +| `seller` | address | Address of the payment recipient | +| `valueAggregate` | uint256 | Total accumulated amount (monotonically increasing) | +| `asset` | address | ERC-20 token contract address | +| `timestamp` | uint64 | Last aggregation timestamp | +| `nonce` | uint256 | Incremented with each aggregation | +| `escrow` | address | Address of the escrow contract | +| `chainId` | uint256 | Network chain ID | +| `expiry` | uint64 | Expiration timestamp | +| `signature` | bytes | EIP-712 signature of the voucher | + +### Collection Structure + +A collection record contains: + +| Field | Type | Description | +|-------|------|-------------| +| `voucherId` | bytes32 | The voucher series ID | +| `voucherNonce` | uint256 | The specific voucher nonce | +| `transactionHash` | bytes32 | On-chain settlement transaction hash | +| `collectedAmount` | uint256 | Amount actually collected on-chain | +| `asset` | address | ERC-20 token contract address | +| `chainId` | uint256 | Network chain ID | +| `collectedAt` | uint64 | Collection timestamp | + +## Core Operations + +### 1. Voucher Storage + +**Operation**: `storeVoucher(voucher)` + +**Purpose**: Persist a new signed voucher received from a buyer. + +**Requirements**: +- MUST reject duplicate vouchers (same id + nonce combination) +- MUST validate all required fields are present +- SHOULD validate signature format (but not cryptographic validity) +- MUST return error if storage fails + +**Use Case**: When a seller receives a new payment voucher from a buyer, either for a new series or an aggregation of an existing series. + +### 2. Voucher Retrieval + +#### Single Voucher Lookup + +**Operation**: `getVoucher(id, nonce?)` + +**Purpose**: Retrieve a specific voucher or the latest in a series. + +**Behavior**: +- When `nonce` provided: Return exact voucher matching (id, nonce) +- When `nonce` omitted: Return voucher with highest nonce for the given id +- Return `null` if no matching voucher exists + +**Use Case**: Get the details of a voucher. + +#### Series Retrieval + +**Operation**: `getVoucherSeries(id, pagination)` + +**Purpose**: Retrieve all vouchers in a series for audit or history tracking. + +**Requirements**: +- MUST return vouchers sorted by nonce (descending - newest first) +- MUST support pagination with configurable limit and offset +- MUST return empty array for non-existent series + +**Pagination Options**: +- `limit`: The maximum number of vouchers to return +- `offset`: The offset of the first voucher to return + +**Use Case**: Display payment history, audit trail, or analyze aggregation patterns. + +#### Query-Based Retrieval + +**Operation**: `getVouchers(query, pagination)` + +**Purpose**: Find vouchers matching specific criteria. + +**Query Options**: +- `buyer`: Filter by buyer address +- `seller`: Filter by seller address +- `latest`: If true, return only highest nonce per series + +**Pagination Options**: +- `limit`: The maximum number of vouchers to return +- `offset`: The offset of the first voucher to return + +**Sorting**: +- Primary: By nonce (descending) +- Secondary: By timestamp (descending) + +**Use Case**: Dashboard views, account reconciliation, payment analytics. + +### 3. Available Voucher Discovery + +**Operation**: `getAvailableVoucher(buyer, seller)` + +**Purpose**: Find the most suitable voucher for aggregation in a new payment. + +**Selection Algorithm**: +1. Filter vouchers matching exact buyer and seller +2. For each series, select the voucher with highest nonce +3. Among selected vouchers, return the one with most recent timestamp +4. Return `null` if no vouchers match + +**Use Case**: When a seller needs to determine which existing voucher to use to aggregate new payments from a returning buyer. + +### 4. Settlement Recording + +**Operation**: `settleVoucher(voucher, txHash, amount)` + +**Purpose**: Record that a voucher has been collected on-chain. + +**Requirements**: +- MUST store the settlement record +- MUST associate with correct voucher (id, nonce) +- MUST record actual collected amount (may differ from voucher amount) +- SHOULD allow multiple collections for same voucher (partial settlements) + +**Use Case**: After successful on-chain collection, record the settlement for reconciliation and tracking. + +### 5. Collection History + +**Operation**: `getVoucherCollections(query, pagination)` + +**Purpose**: Retrieve settlement history for vouchers. + +**Query Options**: +- `id`: Filter by voucher series ID +- `nonce`: Filter by specific nonce (requires id) + +**Pagination Options**: +- `limit`: The maximum number of vouchers to return +- `offset`: The offset of the first voucher to return + +**Use Case**: Reconcile on-chain settlements with off-chain vouchers, audit payment flows. + +## Appendix + +### Reference Implementation + +The `InMemoryVoucherStore` class in the X402 TypeScript package provides a reference implementation suitable for development and testing. Production implementations should follow the same interface while adding appropriate persistence, scaling, and security features. \ No newline at end of file From 94c51ec8e72812d845ebe414d4c5a755c2996bf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 29 Sep 2025 15:32:24 -0300 Subject: [PATCH 074/116] docs: add deferred facilitator spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- specs/schemes/deferred/scheme_deferred_evm.md | 6 +- .../scheme_deferred_evm_facilitator.md | 258 ++++++++++++++++++ specs/x402-specification.md | 69 +++-- 3 files changed, 306 insertions(+), 27 deletions(-) create mode 100644 specs/schemes/deferred/scheme_deferred_evm_facilitator.md diff --git a/specs/schemes/deferred/scheme_deferred_evm.md b/specs/schemes/deferred/scheme_deferred_evm.md index d14bd886e5..ef9fff49bb 100644 --- a/specs/schemes/deferred/scheme_deferred_evm.md +++ b/specs/schemes/deferred/scheme_deferred_evm.md @@ -191,9 +191,11 @@ Example 402 response with an existing voucher: } ``` -### Voucher store specification +### Facilitator specification -Facilitators supporting the `deferred` scheme should offer a persistent voucher store for sellers. For a complete specification see [Voucher Store specification](./voucher_store.md). +Facilitators supporting the `deferred` scheme should implement a voucher store for sellers and new APIs. Specification for these can be found here: +- [Voucher Store specification](./voucher_store.md) +- [Deferred Facilitator specification](./scheme_deferred_evm_facilitator.md) ### Escrow contract specification diff --git a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md new file mode 100644 index 0000000000..473272bb24 --- /dev/null +++ b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md @@ -0,0 +1,258 @@ +# Deferred Facilitator Specification + +## Summary + +This specification defines the REST API endpoints that facilitators must implement to support the `deferred` payment scheme. These endpoints enable sellers to store, retrieve, and settle vouchers through the facilitator's voucher store infrastructure. Vouchers are identified by a unique combination of `id` (64-character hex string) and `nonce` (non-negative integer). + +All endpoints are served under the facilitator's deferred scheme namespace: `${FACILITATOR_URL}/deferred/` + +## Authentication + +Read only endpoints do not require any form of authentication. Any information that can be retrieved by these endpoints will eventually be publicly available on chain. +As for write endpoints, they do not require traditional authentication but instead they rely on verification of signed messages. See each endpoint for details. + +## Required APIs + +### GET /vouchers/available/:buyer/:seller + +Returns the most suitable voucher for aggregation between a buyer-seller pair. + +**Response (200 OK):** +```json +{ + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "5000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1740673000, + "nonce": 2, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1740759400 + }, + "signature": "0x3a2f7e3b..." +} +``` + +**Response (404 Not Found):** No vouchers exist for this pair + +### POST /vouchers + +Stores a new signed voucher in the facilitator's voucher store. + +**Request Body:** +```json +{ + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "6000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1740673100, + "nonce": 3, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1740759400 + }, + "signature": "0x4b3f8e..." +} +``` + +**Response (201 Created):** +```json +{ + "success": true, + "voucherId": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "nonce": 3 +} +``` + +**Response (400 Bad Request):** +```json +{ + "success": false, + "error": "Voucher already exists" +} +``` + +### POST /vouchers/:id/:nonce/settle + +Initiates on-chain settlement of a voucher by calling the escrow contract's `collect` function. + +**Request Body (optional):** +```json +{ + "gasPrice": "20000000000", + "gasLimit": "150000" +} +``` + +**Response (200 OK):** +```json +{ + "success": true, + "transactionHash": "0xabc123...", + "collectedAmount": "6000000", + "network": "base-sepolia" +} +``` + +**Response (400 Bad Request):** +```json +{ + "success": false, + "error": "Voucher not found" +} +``` + +## Optional APIs + +These endpoints are not required for the x402 deferred handshake between a buyer and a seller but might come in handy for audit, visualization or observability purposes. + +### GET /vouchers/:id/:nonce + +Retrieves a specific voucher by ID and nonce. + +**Response (200 OK):** +```json +{ + "voucher": { /* voucher fields */ }, + "signature": "0x3a2f7e3b..." +} +``` + +### GET /vouchers/:id + +Retrieves all vouchers in a series, sorted by nonce (descending). + +**Query Parameters:** +- `limit` (optional): Maximum results (default: 100) +- `offset` (optional): Pagination offset (default: 0) + +**Response (200 OK):** +```json +{ + "vouchers": [ + { + "voucher": { /* voucher fields */ }, + "signature": "0x4b3f8e..." + } + ], + "pagination": { + "limit": 100, + "offset": 0, + "total": 5 + } +} +``` + +### GET /vouchers + +Queries vouchers with filtering. + +**Query Parameters:** +- `buyer` (optional): Filter by buyer address +- `seller` (optional): Filter by seller address +- `latest` (optional): If true, return only highest nonce per series +- `limit` (optional): Maximum results (default: 100) +- `offset` (optional): Pagination offset (default: 0) + +**Response (200 OK):** +```json +{ + "vouchers": [ + { + "voucher": { /* voucher fields */ }, + "signature": "0x3a2f7e3b..." + } + ], + "pagination": { + "limit": 100, + "offset": 0, + "total": 42 + } +} +``` + +### POST /vouchers/:id/:nonce/verify + +Verifies a voucher's validity without settling it. + +**Response (200 OK):** +```json +{ + "valid": true, + "escrowBalance": "10000000", + "collectableAmount": "6000000", + "alreadyCollected": "0" +} +``` + +**Response (200 OK - Invalid):** +```json +{ + "valid": false, + "reason": "Voucher expired" +} +``` + +### GET /vouchers/:id/:nonce/collections + +Retrieves settlement history for a voucher. + +**Query Parameters:** +- `limit` (optional): Maximum results (default: 100) +- `offset` (optional): Pagination offset (default: 0) + +**Response (200 OK):** +```json +{ + "collections": [ + { + "voucherId": "0x9f8d3e4a...", + "voucherNonce": 3, + "transactionHash": "0xabc123...", + "collectedAmount": "6000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "chainId": 84532, + "collectedAt": 1740673200 + } + ], + "pagination": { + "limit": 100, + "offset": 0, + "total": 1 + } +} +``` + +## Error Responses + +All endpoints return standard HTTP status codes: + +- **200 OK**: Successful operation +- **201 Created**: Resource created successfully +- **400 Bad Request**: Invalid request parameters or voucher data +- **401 Unauthorized**: Authentication required or failed +- **403 Forbidden**: Operation not permitted for authenticated user +- **404 Not Found**: Resource not found +- **500 Internal Server Error**: Facilitator error + +Error responses include a JSON body: +```json +{ + "error": "Human-readable error message", + "code": "ERROR_CODE" +} +``` + +## Implementation Notes + +1. **Voucher Storage**: Facilitators MUST implement persistent storage following the [Voucher Store Specification](./voucher_store.md) +2. **Signature Verification**: All voucher signatures MUST be verified before storage +3. **Seller Authorization**: Write operations SHOULD be restricted to the voucher's designated seller +4. **Rate Limiting**: Facilitators MAY implement rate limiting to prevent abuse +5. **Caching**: GET endpoints MAY implement caching for performance diff --git a/specs/x402-specification.md b/specs/x402-specification.md index 88f0753581..cc4aa5d17e 100644 --- a/specs/x402-specification.md +++ b/specs/x402-specification.md @@ -116,7 +116,7 @@ Each payment requirement object in the `accepts` array contains: **5.2.1 JSON Structure** -The client includes payment authorization in the `X-PAYMENT` header as base64-encoded JSON: +The client includes payment authorization in the `X-PAYMENT` header as base64-encoded JSON. For example: ```json { @@ -148,34 +148,13 @@ The Payment Payload contains the following fields: | `x402Version` | `number` | Protocol version identifier (must be 1) | | `scheme` | `string` | Payment scheme identifier (e.g., "exact") | | `network` | `string` | Blockchain network identifier (e.g., "base-sepolia", "ethereum-mainnet") | -| `payload` | `object` | Payment data object | +| `payload` | `object` | Scheme-specific data object | -The `payload` field contains scheme-specific data: - -**All fields are required.** - -| Field Name | Type | Description | -| ---------- | ---- | ----------- | -| `signature` | `string` | EIP-712 signature for authorization | -| `authorization` | `object` | EIP-3009 authorization parameters | - -The authorization object contains the following fields: - -**All fields are required.** - -| Field Name | Type | Description | -| ---------- | ---- | ----------- | -| `from` | `string` | Payer's wallet address | -| `to` | `string` | Recipient's wallet address | -| `value` | `string` | Payment amount in atomic units | -| `validAfter` | `string` | Unix timestamp when authorization becomes valid | -| `validBefore` | `string` | Unix timestamp when authorization expires | -| `nonce` | `string` | 32-byte random nonce to prevent replay attacks | **5.3 Settlement Response** **5.3.1 JSON Structure** -After payment settlement, the server includes transaction details in the `X-PAYMENT-RESPONSE` header as base64-encoded JSON: +After payment settlement, the server includes transaction details in the `X-PAYMENT-RESPONSE` header as base64-encoded JSON. Example: ```json { @@ -238,9 +217,49 @@ The facilitator performs the following verification steps: Settlement is performed by calling the `transferWithAuthorization` function on the ERC-20 contract with the signature and authorization parameters provided in the payment payload. +**6.2 Deferred Scheme** + +The "deferred" scheme enables micropayments through EIP-712 signed vouchers that aggregate off-chain before on-chain settlement. This approach is designed for scenarios where individual payment amounts are smaller than practical transaction costs. + +**6.2.1 EIP-712 Voucher Structure** + +The voucher follows the EIP-712 standard with the following structure: + +```javascript +const voucherTypes = { + Voucher: [ + { name: "id", type: "bytes32" }, + { name: "buyer", type: "address" }, + { name: "seller", type: "address" }, + { name: "valueAggregate", type: "uint256" }, + { name: "asset", type: "address" }, + { name: "timestamp", type: "uint64" }, + { name: "nonce", type: "uint256" }, + { name: "escrow", type: "address" }, + { name: "chainId", type: "uint256" }, + { name: "expiry", type: "uint64" }, + ], +}; +``` + +**6.2.2 Verification Steps** + +The facilitator performs the following verification steps: + +1. **Signature Validation**: Verify the EIP-712 voucher signature is valid +2. **Escrow Balance Check**: Confirm the buyer has sufficient deposited funds in the escrow contract +3. **Voucher Aggregation**: Validate nonce increment and value aggregation if building on existing voucher +4. **Expiry Validation**: Ensure the voucher has not expired +5. **Amount Validation**: Verify valueAggregate covers the required payment amount +6. **Collection Simulation**: Optionally simulate the escrow collection transaction + +**6.2.3 Settlement** + +Settlement occurs when the facilitator calls the `collect` function on the escrow contract with the voucher and signature. Multiple vouchers can be settled in a single transaction using `collectMany`. The escrow contract handles partial collection if insufficient funds are available. + **7. Facilitator Interface** -The facilitator provides REST APIs for payment verification and settlement. This allows resource servers to delegate blockchain operations to trusted third parties or host the endpoints themselves. +The facilitator provides REST APIs for payment verification and settlement. This allows resource servers to delegate blockchain operations to trusted third parties or host the endpoints themselves. The `deferred` scheme adds additional APIs to manage a facilitator voucher store for sellers. The specification for this can be found here: [Deferred Facilitator Spec](./schemes/deferred/scheme_deferred_evm_facilitator.md) **7.1 POST /verify** From 0c930657312291816e0fdc34f43f1a74feb1afae Mon Sep 17 00:00:00 2001 From: Pablo Carranza Velez Date: Mon, 29 Sep 2025 15:56:03 -0300 Subject: [PATCH 075/116] feat: add DeferredPaymentEscrow --- solidity/packages/deferred-escrow/.gitignore | 19 + solidity/packages/deferred-escrow/README.md | 70 ++ .../packages/deferred-escrow/addresses.json | 5 + .../packages/deferred-escrow/foundry.toml | 15 + .../script/CalculateStorageSlot.s.sol | 17 + .../deferred-escrow/script/Deploy.s.sol | 71 ++ .../script/DepositToEscrow.s.sol | 89 +++ .../packages/deferred-escrow/script/README.md | 104 +++ .../packages/deferred-escrow/script/verify.sh | 29 + .../src/DeferredPaymentEscrow.sol | 683 ++++++++++++++++++ .../src/IDeferredPaymentEscrow.sol | 476 ++++++++++++ .../src/libraries/EscrowSignatureLib.sol | 137 ++++ .../deferred-escrow/test/BaseTest.sol | 238 ++++++ .../deferred-escrow/test/DepositTest.t.sol | 286 ++++++++ .../test/ThawWithdrawTest.t.sol | 570 +++++++++++++++ .../test/TokenCompatibilityTest.t.sol | 203 ++++++ .../test/ViewFunctionTest.t.sol | 119 +++ .../test/VoucherCollectionTest.t.sol | 365 ++++++++++ .../test/mocks/MockERC1271.sol | 23 + .../deferred-escrow/test/mocks/MockERC20.sol | 28 + .../test/mocks/MockNonStandardERC20.sol | 64 ++ 21 files changed, 3611 insertions(+) create mode 100644 solidity/packages/deferred-escrow/.gitignore create mode 100644 solidity/packages/deferred-escrow/README.md create mode 100644 solidity/packages/deferred-escrow/addresses.json create mode 100644 solidity/packages/deferred-escrow/foundry.toml create mode 100644 solidity/packages/deferred-escrow/script/CalculateStorageSlot.s.sol create mode 100644 solidity/packages/deferred-escrow/script/Deploy.s.sol create mode 100644 solidity/packages/deferred-escrow/script/DepositToEscrow.s.sol create mode 100644 solidity/packages/deferred-escrow/script/README.md create mode 100755 solidity/packages/deferred-escrow/script/verify.sh create mode 100644 solidity/packages/deferred-escrow/src/DeferredPaymentEscrow.sol create mode 100644 solidity/packages/deferred-escrow/src/IDeferredPaymentEscrow.sol create mode 100644 solidity/packages/deferred-escrow/src/libraries/EscrowSignatureLib.sol create mode 100644 solidity/packages/deferred-escrow/test/BaseTest.sol create mode 100644 solidity/packages/deferred-escrow/test/DepositTest.t.sol create mode 100644 solidity/packages/deferred-escrow/test/ThawWithdrawTest.t.sol create mode 100644 solidity/packages/deferred-escrow/test/TokenCompatibilityTest.t.sol create mode 100644 solidity/packages/deferred-escrow/test/ViewFunctionTest.t.sol create mode 100644 solidity/packages/deferred-escrow/test/VoucherCollectionTest.t.sol create mode 100644 solidity/packages/deferred-escrow/test/mocks/MockERC1271.sol create mode 100644 solidity/packages/deferred-escrow/test/mocks/MockERC20.sol create mode 100644 solidity/packages/deferred-escrow/test/mocks/MockNonStandardERC20.sol diff --git a/solidity/packages/deferred-escrow/.gitignore b/solidity/packages/deferred-escrow/.gitignore new file mode 100644 index 0000000000..e2e047d41f --- /dev/null +++ b/solidity/packages/deferred-escrow/.gitignore @@ -0,0 +1,19 @@ +# Compiler files +cache/ +out/ + +# Ignores development broadcast logs +!/broadcast +/broadcast/*/31337/ +/broadcast/**/dry-run/ + +# Docs (auto-generated) +# docs/ + +# Dotenv file +.env + +# Coverage output +lcov.info + +broadcast/ \ No newline at end of file diff --git a/solidity/packages/deferred-escrow/README.md b/solidity/packages/deferred-escrow/README.md new file mode 100644 index 0000000000..073528c13f --- /dev/null +++ b/solidity/packages/deferred-escrow/README.md @@ -0,0 +1,70 @@ +## A2AP Contracts + +These contracts will implement the escrowing and vouchers mechanism needed for the `deferred` x402 payment scheme. + +The main contract is DeferredPaymentEscrow.sol. + +## Usage + +### Build + +```shell +$ forge build +``` + +### Test + +```shell +$ forge test +``` + +### Format + +```shell +$ forge fmt +``` + +### Gas Snapshots + +```shell +$ forge snapshot +``` + +### Anvil + +```shell +$ anvil +``` + +### Deploy + +Deploy the DeferredPaymentEscrow contract with UUPS proxy: + +```shell +$ forge script script/DeployDeferredPaymentEscrow.s.sol --rpc-url --private-key --broadcast +``` + +For testnet/mainnet deployment with verification: + +```shell +$ forge script script/DeployDeferredPaymentEscrow.s.sol \ + --rpc-url \ + --private-key \ + --broadcast \ + --verify \ + --etherscan-api-key +``` + +### Cast + +```shell +$ cast +``` + +### Help + +```shell +$ forge --help +$ anvil --help +$ cast --help +``` diff --git a/solidity/packages/deferred-escrow/addresses.json b/solidity/packages/deferred-escrow/addresses.json new file mode 100644 index 0000000000..ad86e6f22a --- /dev/null +++ b/solidity/packages/deferred-escrow/addresses.json @@ -0,0 +1,5 @@ +{ + "84532": { + "deferredPaymentEscrow": "0xF1308b39EdB10E5163581C1f8D0Bf8E26404A11f" + } +} diff --git a/solidity/packages/deferred-escrow/foundry.toml b/solidity/packages/deferred-escrow/foundry.toml new file mode 100644 index 0000000000..eddafc4796 --- /dev/null +++ b/solidity/packages/deferred-escrow/foundry.toml @@ -0,0 +1,15 @@ +[profile.default] +src = "src" +out = "out" +libs = ["lib"] +remappings = [ + "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", + "forge-std/=lib/forge-std/src/", + "safe-singleton-deployer/=lib/safe-singleton-deployer-sol/src/" +] +fs_permissions = [{ access = "read", path = "./addresses.json" }] +optimizer = true +optimizer_runs = 200 +via_ir = true + +# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/solidity/packages/deferred-escrow/script/CalculateStorageSlot.s.sol b/solidity/packages/deferred-escrow/script/CalculateStorageSlot.s.sol new file mode 100644 index 0000000000..a6e1a7240e --- /dev/null +++ b/solidity/packages/deferred-escrow/script/CalculateStorageSlot.s.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {Script, console} from "forge-std/Script.sol"; +import {SlotDerivation} from "@openzeppelin/contracts/utils/SlotDerivation.sol"; + +contract CalculateStorageSlot is Script { + using SlotDerivation for string; + + function run() public { + string memory namespace = "deferred.payment.escrow.main"; + bytes32 slot = namespace.erc7201Slot(); + console.log("Namespace:", namespace); + console.log("Storage slot:"); + console.logBytes32(slot); + } +} diff --git a/solidity/packages/deferred-escrow/script/Deploy.s.sol b/solidity/packages/deferred-escrow/script/Deploy.s.sol new file mode 100644 index 0000000000..a1765b09d7 --- /dev/null +++ b/solidity/packages/deferred-escrow/script/Deploy.s.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {Script, console} from "forge-std/Script.sol"; +import {SafeSingletonDeployer} from "safe-singleton-deployer/SafeSingletonDeployer.sol"; +import {DeferredPaymentEscrow} from "../src/DeferredPaymentEscrow.sol"; + +contract Deploy is Script { + // Use meaningful salt for deterministic addresses across chains + bytes32 constant ESCROW_SALT = keccak256("DeferredPaymentEscrow.v1"); + + function run() external returns (address escrow) { + // Default deployment parameters + uint256 thawingPeriod = 1 days; // 86400 seconds + + console.log("=== Deploying DeferredPaymentEscrow ==="); + console.log("Deployer:", msg.sender); + console.log("Thawing Period:", thawingPeriod); + console.log(""); + + vm.startBroadcast(); + + // Deploy DeferredPaymentEscrow using Safe Singleton Factory + console.log("Deploying DeferredPaymentEscrow..."); + escrow = _deploySingleton( + type(DeferredPaymentEscrow).creationCode, abi.encode(thawingPeriod), ESCROW_SALT, "DeferredPaymentEscrow" + ); + + vm.stopBroadcast(); + + // Verify deployment + DeferredPaymentEscrow escrowContract = DeferredPaymentEscrow(escrow); + require(escrowContract.THAWING_PERIOD() == thawingPeriod, "Deployment failed"); + + // Log deployment summary + console.log(""); + console.log("=== Deployment Summary ==="); + console.log("DeferredPaymentEscrow:", escrow); + console.log(""); + console.log("This address will be consistent across all chains!"); + console.log("========================="); + } + + function _deploySingleton( + bytes memory creationCode, + bytes memory constructorArgs, + bytes32 salt, + string memory contractName + ) internal returns (address deployed) { + // Use SafeSingletonDeployer.deploy (not broadcastDeploy) since we're already broadcasting + deployed = SafeSingletonDeployer.deploy(creationCode, constructorArgs, salt); + + console.log(string.concat(contractName, " deployed at:"), deployed); + + // Verify deployment + require(deployed.code.length > 0, string.concat(contractName, " deployment failed")); + } + + // Helper function to predict addresses without deploying + function predict() external pure { + console.log("=== Predicted Addresses ==="); + + // Predict DeferredPaymentEscrow address + address predictedEscrow = SafeSingletonDeployer.computeAddress( + type(DeferredPaymentEscrow).creationCode, abi.encode(1 days), ESCROW_SALT + ); + console.log("DeferredPaymentEscrow:", predictedEscrow); + + console.log("==========================="); + } +} diff --git a/solidity/packages/deferred-escrow/script/DepositToEscrow.s.sol b/solidity/packages/deferred-escrow/script/DepositToEscrow.s.sol new file mode 100644 index 0000000000..2efb25a6c0 --- /dev/null +++ b/solidity/packages/deferred-escrow/script/DepositToEscrow.s.sol @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {Script, console} from "forge-std/Script.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IDeferredPaymentEscrow} from "../src/IDeferredPaymentEscrow.sol"; + +contract DepositToEscrow is Script { + address constant DEFAULT_TOKEN = 0x036CbD53842c5426634e7929541eC2318f3dCF7e; // USDC + uint256 constant DEFAULT_AMOUNT = 10_000; // 0.01 USDC + + function run() external { + // Get escrow address based on chain ID + address escrowAddress = getEscrowAddress(); + require(escrowAddress != address(0), "Escrow address not found for this chain"); + + // Get parameters from environment variables or use defaults + address seller = vm.envOr("SELLER", address(0)); + address token = vm.envOr("TOKEN", DEFAULT_TOKEN); + uint256 amount = vm.envOr("AMOUNT", DEFAULT_AMOUNT); + + // Validate inputs + require(seller != address(0), "Seller address must be provided via SELLER env var"); + require(token != address(0), "Non-zero token address must be provided via TOKEN env var"); + require(amount > 0, "Amount must be provided via AMOUNT env var"); + + // Log deposit parameters + console.log("Depositing to DeferredPaymentEscrow..."); + console.log(" Escrow:", escrowAddress); + console.log(" Seller:", seller); + console.log(" Token:", token); + console.log(" Amount:", amount); + + // Start broadcasting transactions + vm.startBroadcast(); + + // Get token contract + IERC20 tokenContract = IERC20(token); + + // Check current allowance + uint256 currentAllowance = tokenContract.allowance(msg.sender, escrowAddress); + console.log(" Current allowance:", currentAllowance); + + // Approve if needed + if (currentAllowance < amount) { + console.log(" Approving escrow to spend tokens..."); + tokenContract.approve(escrowAddress, amount); + } + + // Get escrow contract + IDeferredPaymentEscrow escrow = IDeferredPaymentEscrow(escrowAddress); + + // Check balance before deposit + IDeferredPaymentEscrow.EscrowAccount memory accountBefore = escrow.getAccount(msg.sender, seller, token); + console.log(" Balance before:", accountBefore.balance); + + // Deposit tokens + escrow.deposit(seller, token, amount); + + // Check balance after deposit + IDeferredPaymentEscrow.EscrowAccount memory accountAfter = escrow.getAccount(msg.sender, seller, token); + console.log(" Balance after:", accountAfter.balance); + + vm.stopBroadcast(); + + console.log("\n=== Deposit Summary ==="); + console.log("Deposited:", amount); + console.log("From buyer:", msg.sender); + console.log("To seller:", seller); + console.log("Token:", token); + console.log("New balance:", accountAfter.balance); + console.log("======================"); + } + + function getEscrowAddress() internal view returns (address) { + uint256 chainId = block.chainid; + + // Read addresses from JSON file + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/addresses.json"); + string memory json = vm.readFile(path); + + // Parse JSON to get escrow address for current chain + string memory key = string.concat(".", vm.toString(chainId), ".deferredPaymentEscrow"); + address escrowAddress = vm.parseJsonAddress(json, key); + + return escrowAddress; + } +} diff --git a/solidity/packages/deferred-escrow/script/README.md b/solidity/packages/deferred-escrow/script/README.md new file mode 100644 index 0000000000..c33f0e7398 --- /dev/null +++ b/solidity/packages/deferred-escrow/script/README.md @@ -0,0 +1,104 @@ +# Deployment Scripts + +This directory contains deployment scripts for the DeferredPaymentEscrow contract. + +## Scripts + +### Deploy.s.sol +Main deployment script that deploys the DeferredPaymentEscrow contract using Safe Singleton Factory for deterministic addresses across all chains. + +**Default Parameters:** +- Thawing Period: 1 day (immutable, cannot be changed post-deployment) + +**Key Features:** +- No proxy pattern - direct contract deployment +- Deterministic addresses across all chains using Safe Singleton Factory +- Fully permissionless (no owner functionality) +- Immutable thawing period set in constructor + +### CalculateStorageSlot.s.sol +Utility script to calculate ERC-7201 storage slots for namespaced storage. + +### DepositToEscrow.s.sol +Script to deposit ERC20 tokens into the DeferredPaymentEscrow contract for specific sellers. + +### verify.sh +Bash script to verify the deployed contract on Etherscan/Basescan. Follows the same pattern as account-modules for consistency. + +## Usage + +### Local Deployment (Anvil) +```bash +# Start local node +anvil + +# Deploy to local network +forge script script/Deploy.s.sol --rpc-url http://localhost:8545 --broadcast --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +``` + +### Predict Contract Address +```bash +# Get the deterministic address before deployment +forge script script/Deploy.s.sol --sig "predict()" --rpc-url +``` + +### Testnet/Mainnet Deployment +```bash +# Deploy (verification done separately) +forge script script/Deploy.s.sol \ + --rpc-url \ + --private-key \ + --broadcast + +# Verify separately using verify.sh script +./script/verify.sh base-sepolia +``` + +### Depositing Funds + +To deposit tokens for a seller: +```bash +SELLER= TOKEN= AMOUNT= \ +forge script script/DepositToEscrow.s.sol \ + --rpc-url \ + --private-key \ + --broadcast +``` + +Example: +```bash +# Deposit 100 USDC (6 decimals) to a seller +SELLER=0x1234...5678 TOKEN=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 AMOUNT=100000000 \ +forge script script/DepositToEscrow.s.sol \ + --rpc-url https://mainnet.infura.io/v3/YOUR_KEY \ + --private-key $PRIVATE_KEY \ + --broadcast +``` + +## Output + +The deployment script will output: +- Single contract address (no proxy/implementation split) +- Note that the address will be consistent across all chains due to deterministic deployment + +The deposit script will output: +- Escrow address being used +- Seller, token, and amount details +- Balance before and after deposit +- Transaction summary + +## Important Notes + +1. **Deterministic Deployment**: The DeferredPaymentEscrow contract uses Safe Singleton Factory, ensuring the same address across all chains regardless of deployer. Use the `predict()` function to get the address before deployment. + +2. **Immutable Configuration**: The thawing period is set during deployment and cannot be changed. There is no owner or admin functionality. + +3. **Verification**: Use the provided `verify.sh` script for contract verification. The script includes constructor arguments for the thawing period. + +4. **Library Dependencies**: The contract uses EscrowSignatureLib which Forge deploys automatically. The verify script handles this correctly. + +5. For the deposit script: + - The script automatically reads the deployed escrow address from `addresses.json` based on the current chain ID + - Token approval is handled automatically if needed + - For batch deposits, ensure the arrays have the same length + - The depositor must have sufficient token balance and the tokens must be ERC20 compliant diff --git a/solidity/packages/deferred-escrow/script/verify.sh b/solidity/packages/deferred-escrow/script/verify.sh new file mode 100755 index 0000000000..1d072439db --- /dev/null +++ b/solidity/packages/deferred-escrow/script/verify.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Script to verify deployed contracts on Basescan/Etherscan +# Usage: ./verify.sh [network] +# Example: ./verify.sh base-sepolia + +NETWORK=${1:-base-sepolia} + +# Contract address (same on all chains due to Safe Singleton Factory) +ESCROW_ADDRESS="0xF1308b39EdB10E5163581C1f8D0Bf8E26404A11f" + +echo "Verifying contracts on $NETWORK..." +echo "" + +# Verify DeferredPaymentEscrow +echo "Verifying DeferredPaymentEscrow at $ESCROW_ADDRESS..." +forge verify-contract \ + --chain $NETWORK \ + --num-of-optimizations 200 \ + --compiler-version v0.8.30 \ + --constructor-args $(cast abi-encode "constructor(uint256)" 86400) \ + $ESCROW_ADDRESS \ + src/DeferredPaymentEscrow.sol:DeferredPaymentEscrow + +echo "" +echo "Verification complete!" +echo "" +echo "View verified contract:" +echo "- DeferredPaymentEscrow: https://sepolia.basescan.org/address/$ESCROW_ADDRESS#code" diff --git a/solidity/packages/deferred-escrow/src/DeferredPaymentEscrow.sol b/solidity/packages/deferred-escrow/src/DeferredPaymentEscrow.sol new file mode 100644 index 0000000000..47dc1fb078 --- /dev/null +++ b/solidity/packages/deferred-escrow/src/DeferredPaymentEscrow.sol @@ -0,0 +1,683 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; +import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import {IDeferredPaymentEscrow} from "./IDeferredPaymentEscrow.sol"; +import {EscrowSignatureLib} from "./libraries/EscrowSignatureLib.sol"; + +/** + * @title DeferredPaymentEscrow + * @notice Multi-token escrow system supporting off-chain vouchers for micropayments + * @dev Implements EIP-712 signed vouchers with ERC-1271 smart account support + */ +contract DeferredPaymentEscrow is ReentrancyGuard, EIP712, IDeferredPaymentEscrow { + using SafeERC20 for IERC20; + using EnumerableSet for EnumerableSet.Bytes32Set; + + /// @notice Maximum allowed thawing period (30 days) + uint256 public constant MAX_THAWING_PERIOD = 30 days; + + /// @notice Immutable thawing period for withdrawals + uint256 public immutable THAWING_PERIOD; + + /// @notice EIP-712 type hash for voucher structure + bytes32 public constant VOUCHER_TYPEHASH = EscrowSignatureLib.VOUCHER_TYPEHASH; + + /// @notice EIP-712 type hash for deposit authorization structure + bytes32 public constant DEPOSIT_AUTHORIZATION_TYPEHASH = EscrowSignatureLib.DEPOSIT_AUTHORIZATION_TYPEHASH; + + /// @notice EIP-712 type hash for flush authorization structure + bytes32 public constant FLUSH_AUTHORIZATION_TYPEHASH = EscrowSignatureLib.FLUSH_AUTHORIZATION_TYPEHASH; + + /// @notice EIP-712 type hash for flush all authorization structure + bytes32 public constant FLUSH_ALL_AUTHORIZATION_TYPEHASH = EscrowSignatureLib.FLUSH_ALL_AUTHORIZATION_TYPEHASH; + + /// @notice Struct to store seller and asset information for escrow keys + struct EscrowKey { + address seller; + address asset; + } + + /// @custom:storage-location erc7201:deferred.payment.escrow.main + struct MainStorage { + /// @notice Triple-nested mapping: buyer => seller => asset => EscrowAccount + mapping( + address buyer => mapping(address seller => mapping(address asset => IDeferredPaymentEscrow.EscrowAccount)) + ) accounts; + /// @notice Quadruple-nested mapping: buyer => seller => asset => voucherId => collected amount + mapping( + address buyer => mapping(address seller => mapping(address asset => mapping(bytes32 voucherId => uint256))) + ) voucherCollected; + /// @notice Set of hashed (seller, asset) pairs per buyer for account tracking + mapping(address buyer => EnumerableSet.Bytes32Set) buyerEscrowKeys; + /// @notice Decode hash back to (seller, asset) + mapping(bytes32 keyHash => EscrowKey) escrowKeyToInfo; + /// @notice Track used deposit authorization nonces by buyer and nonce + mapping(address buyer => mapping(bytes32 nonce => bool)) usedDepositNonces; + /// @notice Track used flush authorization nonces by buyer and nonce + mapping(address buyer => mapping(bytes32 nonce => bool)) usedFlushNonces; + /// @notice Track used flush all authorization nonces by buyer and nonce + mapping(address buyer => mapping(bytes32 nonce => bool)) usedFlushAllNonces; + } + + // keccak256(abi.encode(uint256(keccak256("deferred.payment.escrow.main")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 constant MAIN_STORAGE_LOCATION = 0x4cf6ea8df9d6256fc1076c222eae360b1d94159d5580e17aba1e651f33b72300; + + function _getMainStorage() private pure returns (MainStorage storage $) { + assembly { + $.slot := MAIN_STORAGE_LOCATION + } + } + + /** + * @notice Constructor + * @param _thawingPeriod Thawing period in seconds + */ + constructor(uint256 _thawingPeriod) EIP712("DeferredPaymentEscrow", "1") { + require(_thawingPeriod <= MAX_THAWING_PERIOD, InvalidThawingPeriod(_thawingPeriod, MAX_THAWING_PERIOD)); + + THAWING_PERIOD = _thawingPeriod; + } + + /** + * @notice Deposit tokens into escrow for a specific seller and asset + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + */ + function deposit(address seller, address asset, uint256 amount) external nonReentrant { + _deposit(msg.sender, seller, asset, amount, msg.sender); + } + + /** + * @notice Deposit tokens into escrow on behalf of a buyer + * @param buyer Address of the buyer who will own the escrow + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + */ + function depositTo(address buyer, address seller, address asset, uint256 amount) external nonReentrant { + require(buyer != address(0), InvalidAddress(buyer)); + _deposit(buyer, seller, asset, amount, msg.sender); + } + + /** + * @notice Deposit tokens for multiple sellers with a single asset in a single transaction + * @param asset ERC-20 token address + * @param deposits Array of deposit inputs + */ + function depositMany(address asset, DepositInput[] calldata deposits) external nonReentrant { + require(asset != address(0), InvalidAsset(asset)); + require(deposits.length != 0, NoDepositsProvided()); + + MainStorage storage $ = _getMainStorage(); + uint256 totalAmount = 0; + + // Single loop: validate inputs, calculate total, and update balances + for (uint256 i = 0; i < deposits.length; i++) { + DepositInput calldata depositInput = deposits[i]; + require(depositInput.seller != address(0), InvalidAddress(depositInput.seller)); + require(depositInput.amount != 0, InvalidAmount(depositInput.amount)); + + totalAmount += depositInput.amount; + + // Update account balance + EscrowAccount storage account = $.accounts[msg.sender][depositInput.seller][asset]; + account.balance += depositInput.amount; + + // Track account in buyerEscrowKeys set + bytes32 key = keccak256(abi.encodePacked(depositInput.seller, asset)); + if ($.buyerEscrowKeys[msg.sender].add(key)) { + $.escrowKeyToInfo[key] = EscrowKey(depositInput.seller, asset); + } + + emit Deposited(msg.sender, depositInput.seller, asset, depositInput.amount, account.balance); + } + + // Single token transfer for all deposits + IERC20(asset).safeTransferFrom(msg.sender, address(this), totalAmount); + } + + /** + * @notice Deposit tokens using EIP-712 signed authorization + * @param auth The deposit authorization struct + * @param signature Buyer's signature for the authorization + */ + function depositWithAuthorization(DepositAuthorization calldata auth, bytes calldata signature) + external + nonReentrant + { + // Check expiry + require(block.timestamp <= auth.expiry, AuthorizationExpired(auth.expiry, block.timestamp)); + + // Check and mark nonce as used + MainStorage storage $ = _getMainStorage(); + require(!$.usedDepositNonces[auth.buyer][auth.nonce], NonceAlreadyUsed(auth.nonce)); + $.usedDepositNonces[auth.buyer][auth.nonce] = true; + + // Validate signature + require( + EscrowSignatureLib.isDepositAuthorizationValid(auth, signature, _domainSeparatorV4()), + InvalidAuthorization() + ); + + // Use internal _deposit function for consistency + _deposit(auth.buyer, auth.seller, auth.asset, auth.amount, auth.buyer); + + // Emit authorization-specific event + emit DepositAuthorized(auth.buyer, auth.seller, auth.asset, auth.amount, auth.nonce); + } + + /** + * @notice Initiate or increase withdrawal thawing amount (starts/resets thawing period) + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to add to thawing + */ + function thaw(address seller, address asset, uint256 amount) external { + require(seller != address(0), InvalidAddress(seller)); + require(asset != address(0), InvalidAsset(asset)); + require(amount != 0, InvalidAmount(amount)); + + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[msg.sender][seller][asset]; + + // Check if the requested thaw amount can be accommodated + uint256 newThawingAmount = account.thawingAmount + amount; + require(account.balance >= newThawingAmount, InsufficientBalance(account.balance, newThawingAmount)); + + _thaw(msg.sender, seller, asset, amount); + } + + /** + * @notice Cancel an ongoing thawing process + * @param seller Address of the seller + * @param asset ERC-20 token address + */ + function cancelThaw(address seller, address asset) external { + require(seller != address(0), InvalidAddress(seller)); + require(asset != address(0), InvalidAsset(asset)); + + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[msg.sender][seller][asset]; + require(account.thawingAmount != 0, NoThawingInProgress(msg.sender, seller, asset)); + + uint256 thawingAmount = account.thawingAmount; + + // Cancel thawing (no balance change needed) + account.thawingAmount = 0; + account.thawEndTime = 0; + + emit ThawCancelled(msg.sender, seller, asset, thawingAmount); + } + + /** + * @notice Complete withdrawal after thawing period + * @param seller Address of the seller + * @param asset ERC-20 token address + */ + function withdraw(address seller, address asset) external nonReentrant { + require(seller != address(0), InvalidAddress(seller)); + require(asset != address(0), InvalidAsset(asset)); + + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[msg.sender][seller][asset]; + + // Check if there's thawing in progress + require(account.thawingAmount > 0, NoThawingInProgress(msg.sender, seller, asset)); + + // Check if thawing period is complete + require(block.timestamp >= account.thawEndTime, ThawingPeriodNotCompleted(block.timestamp, account.thawEndTime)); + + // Perform the withdrawal + _withdraw(msg.sender, seller, asset); + } + + /** + * @notice Initiate or complete flush using EIP-712 signed authorization + * @dev "Flush" performs two operations on a specific escrow account: + * 1. Withdraws any funds that have completed their thawing period (ready to withdraw) + * 2. Initiates thawing for any remaining balance that isn't already thawing + * This allows a Facilitator to help a buyer recover their funds with just a signature. + * @param auth The flush authorization struct containing buyer, seller, asset, nonce, and expiry + * @param signature Buyer's signature for the authorization + */ + function flushWithAuthorization(FlushAuthorization calldata auth, bytes calldata signature) external nonReentrant { + // Check expiry + require(block.timestamp <= auth.expiry, AuthorizationExpired(auth.expiry, block.timestamp)); + + // Check and mark nonce as used + MainStorage storage $ = _getMainStorage(); + require(!$.usedFlushNonces[auth.buyer][auth.nonce], NonceAlreadyUsed(auth.nonce)); + $.usedFlushNonces[auth.buyer][auth.nonce] = true; + + // Validate signature + require( + EscrowSignatureLib.isFlushAuthorizationValid(auth, signature, _domainSeparatorV4()), InvalidAuthorization() + ); + + // First, withdraw any funds that are ready + _withdraw(auth.buyer, auth.seller, auth.asset); + + // Then, calculate and thaw any remaining balance that isn't already thawing + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[auth.buyer][auth.seller][auth.asset]; + uint256 availableToThaw = account.balance > account.thawingAmount ? account.balance - account.thawingAmount : 0; + + uint256 thawedAmount = 0; + if (availableToThaw > 0) { + thawedAmount = _thaw(auth.buyer, auth.seller, auth.asset, availableToThaw); + } + + // Emit the flush event (even if nothing happened - idempotent operation) + emit FlushAuthorized(auth.buyer, auth.seller, auth.asset, auth.nonce, thawedAmount > 0); + } + + /** + * @notice Flush all escrows for a buyer using EIP-712 signed authorization + * @dev "Flush all" performs a flush operation on ALL of a buyer's escrow accounts: + * For each account: + * 1. Withdraws any funds that have completed their thawing period (ready to withdraw) + * 2. Initiates thawing for any remaining balance that isn't already thawing + * This allows a Facilitator to help a buyer recover all their escrowed funds across + * all sellers and assets with just a single signature. + * @param auth The flush all authorization struct containing buyer, nonce, and expiry + * @param signature Buyer's signature for the authorization + */ + function flushAllWithAuthorization(FlushAllAuthorization calldata auth, bytes calldata signature) + external + nonReentrant + { + // Check expiry + require(block.timestamp <= auth.expiry, AuthorizationExpired(auth.expiry, block.timestamp)); + + // Check and mark nonce as used + MainStorage storage $ = _getMainStorage(); + require(!$.usedFlushAllNonces[auth.buyer][auth.nonce], NonceAlreadyUsed(auth.nonce)); + $.usedFlushAllNonces[auth.buyer][auth.nonce] = true; + + // Validate signature + require( + EscrowSignatureLib.isFlushAllAuthorizationValid(auth, signature, _domainSeparatorV4()), + InvalidAuthorization() + ); + + uint256 accountsFlushed = 0; + + // Get all escrow keys for this buyer + EnumerableSet.Bytes32Set storage escrowKeys = $.buyerEscrowKeys[auth.buyer]; + uint256 keysLength = escrowKeys.length(); + + // Process each account: withdraw ready funds AND thaw remaining balance + // Iterate backwards to handle removals safely + for (uint256 i = keysLength; i > 0; i--) { + bytes32 escrowKey = escrowKeys.at(i - 1); + EscrowKey storage keyInfo = $.escrowKeyToInfo[escrowKey]; + + // First, withdraw any funds that are ready + uint256 withdrawnAmount = _withdraw(auth.buyer, keyInfo.seller, keyInfo.asset); + + // Then, calculate and thaw any remaining balance that isn't already thawing + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[auth.buyer][keyInfo.seller][keyInfo.asset]; + uint256 availableToThaw = + account.balance > account.thawingAmount ? account.balance - account.thawingAmount : 0; + + uint256 thawedAmount = 0; + if (availableToThaw > 0) { + thawedAmount = _thaw(auth.buyer, keyInfo.seller, keyInfo.asset, availableToThaw); + } + + // Count accounts that had activity + if (withdrawnAmount > 0 || thawedAmount > 0) { + accountsFlushed++; + } + } + + emit FlushAllAuthorized(auth.buyer, auth.nonce, accountsFlushed); + } + + /** + * @notice Collect a single voucher + * @param voucher The voucher to collect + * @param signature Buyer's signature for the voucher + */ + function collect(Voucher calldata voucher, bytes calldata signature) external nonReentrant { + _collectVoucher(voucher, signature); + } + + /** + * @notice Collect multiple vouchers in a single transaction + * @param vouchers Array of signed vouchers + */ + function collectMany(SignedVoucher[] calldata vouchers) external nonReentrant { + require(vouchers.length != 0, NoVouchersProvided()); + + for (uint256 i = 0; i < vouchers.length; i++) { + _collectVoucher(vouchers[i].voucher, vouchers[i].signature); + } + } + + /** + * @notice Get escrow account details for a buyer-seller-asset combination + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @return EscrowAccount struct with balance, thawing amount, and thaw end time + */ + function getAccount(address buyer, address seller, address asset) external view returns (EscrowAccount memory) { + return _getMainStorage().accounts[buyer][seller][asset]; + } + + /** + * @notice Get the amount already collected for a specific voucher + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param voucherId Unique identifier of the voucher + * @return Amount already collected + */ + function getVoucherCollected(address buyer, address seller, address asset, bytes32 voucherId) + external + view + returns (uint256) + { + return _getMainStorage().voucherCollected[buyer][seller][asset][voucherId]; + } + + /** + * @notice Calculate the outstanding and collectable amounts for a voucher + * @param voucher The voucher to check + * @return outstanding Total amount still owed on the voucher + * @return collectable Amount that can actually be collected now (considering available balance) + */ + function getOutstandingAndCollectableAmount(Voucher calldata voucher) + external + view + returns (uint256 outstanding, uint256 collectable) + { + MainStorage storage $ = _getMainStorage(); + uint256 alreadyCollected = $.voucherCollected[voucher.buyer][voucher.seller][voucher.asset][voucher.id]; + return _getOutstandingAndCollectableAmount(voucher, alreadyCollected); + } + + /** + * @notice Validate a voucher signature + * @param voucher The voucher to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isVoucherSignatureValid(Voucher calldata voucher, bytes calldata signature) external view returns (bool) { + return EscrowSignatureLib.isVoucherSignatureValid(voucher, signature, _domainSeparatorV4()); + } + + /** + * @notice Validate a deposit authorization signature + * @param auth The deposit authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isDepositAuthorizationValid(DepositAuthorization calldata auth, bytes calldata signature) + external + view + returns (bool) + { + return EscrowSignatureLib.isDepositAuthorizationValid(auth, signature, _domainSeparatorV4()); + } + + /** + * @notice Validate a flush authorization signature + * @param auth The flush authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isFlushAuthorizationValid(FlushAuthorization calldata auth, bytes calldata signature) + external + view + returns (bool) + { + return EscrowSignatureLib.isFlushAuthorizationValid(auth, signature, _domainSeparatorV4()); + } + + /** + * @notice Validate a flush all authorization signature + * @param auth The flush all authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isFlushAllAuthorizationValid(FlushAllAuthorization calldata auth, bytes calldata signature) + external + view + returns (bool) + { + return EscrowSignatureLib.isFlushAllAuthorizationValid(auth, signature, _domainSeparatorV4()); + } + + /** + * @notice Get the EIP-712 domain separator + * @return Domain separator hash + */ + function DOMAIN_SEPARATOR() external view returns (bytes32) { + return _domainSeparatorV4(); + } + + /** + * @notice Internal function to collect a voucher + * @param voucher The voucher to collect + * @param signature Buyer's signature for the voucher + */ + function _collectVoucher(Voucher calldata voucher, bytes calldata signature) internal { + // Validate basic voucher parameters + require(voucher.buyer != address(0), InvalidAddress(voucher.buyer)); + require(voucher.asset != address(0), InvalidAsset(voucher.asset)); + require(voucher.escrow == address(this), InvalidEscrow(voucher.escrow, address(this))); + require(voucher.chainId == block.chainid, InvalidChainId(voucher.chainId, block.chainid)); + require(voucher.valueAggregate != 0, InvalidAmount(voucher.valueAggregate)); + require(block.timestamp <= voucher.expiry, VoucherExpired(voucher.id, block.timestamp, voucher.expiry)); + + // Validate signature + require( + EscrowSignatureLib.isVoucherSignatureValid(voucher, signature, _domainSeparatorV4()), + InvalidSignature(voucher.id, voucher.buyer) + ); + + MainStorage storage $ = _getMainStorage(); + + // Get current collected amount and calculate what can be collected + uint256 alreadyCollected = $.voucherCollected[voucher.buyer][voucher.seller][voucher.asset][voucher.id]; + (uint256 outstanding, uint256 collectAmount) = _getOutstandingAndCollectableAmount(voucher, alreadyCollected); + + if (outstanding == 0) { + // Voucher is already fully collected + emit VoucherAlreadyCollected(voucher.id, voucher.buyer, voucher.seller, voucher.asset, alreadyCollected); + return; + } + + if (collectAmount == 0) { + // Voucher has outstanding amount but no balance available + emit VoucherNoCollectableBalance( + voucher.id, voucher.buyer, voucher.seller, voucher.asset, outstanding, alreadyCollected + ); + return; + } + + // Proceed with collection + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[voucher.buyer][voucher.seller][voucher.asset]; + + // Update state + $.voucherCollected[voucher.buyer][voucher.seller][voucher.asset][voucher.id] = alreadyCollected + collectAmount; + + // Deduct from balance + account.balance -= collectAmount; + + // If balance drops below thawing amount, adjust thawing amount + if (account.balance < account.thawingAmount) { + account.thawingAmount = account.balance; + } + + // Transfer tokens directly to seller (no protocol fee) + IERC20(voucher.asset).safeTransfer(voucher.seller, collectAmount); + + emit VoucherCollected( + voucher.id, voucher.buyer, voucher.seller, voucher.asset, collectAmount, alreadyCollected + collectAmount + ); + + // Clean up if account is empty + if (account.balance == 0 && account.thawingAmount == 0) { + bytes32 key = keccak256(abi.encodePacked(voucher.seller, voucher.asset)); + $.buyerEscrowKeys[voucher.buyer].remove(key); + } + } + + /** + * @notice Internal function to handle deposits + * @param buyer Address of the buyer who will own the escrow + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + * @param payer Address paying for the deposit + */ + function _deposit(address buyer, address seller, address asset, uint256 amount, address payer) internal { + require(seller != address(0), InvalidAddress(seller)); + require(asset != address(0), InvalidAsset(asset)); + require(amount != 0, InvalidAmount(amount)); + + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[buyer][seller][asset]; + + // Transfer tokens from payer to this contract + IERC20(asset).safeTransferFrom(payer, address(this), amount); + + // Update account balance + account.balance += amount; + + // Track account in buyerEscrowKeys set + bytes32 key = keccak256(abi.encodePacked(seller, asset)); + if ($.buyerEscrowKeys[buyer].add(key)) { + $.escrowKeyToInfo[key] = EscrowKey(seller, asset); + } + + emit Deposited(buyer, seller, asset, amount, account.balance); + } + + /** + * @notice Internal function to initiate or increase thawing + * @dev This function will NOT revert if the requested amount exceeds the available balance. + * Instead, it will cap the thaw amount to the maximum available (balance - already thawing). + * If funds are already thawing, this will ADD to the thawing amount and reset the timer. + * The thaw timer always resets to a full thawing period from the current timestamp, + * regardless of any previous thaw progress. + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to thaw (must be > 0) + * @return thawedAmount The actual amount that was set to thaw (may be less than requested if capped) + */ + function _thaw(address buyer, address seller, address asset, uint256 amount) + internal + returns (uint256 thawedAmount) + { + require(amount > 0, InvalidAmount(amount)); + + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[buyer][seller][asset]; + + // Calculate how much can be thawed + uint256 availableToThaw = account.balance - account.thawingAmount; + if (availableToThaw == 0) { + return 0; // Nothing to thaw + } + + // Cap to available amount + thawedAmount = amount > availableToThaw ? availableToThaw : amount; + + // Store previous values for event + uint256 previousThawingAmount = account.thawingAmount; + uint256 previousThawEndTime = account.thawEndTime; + + // Update thawing state + account.thawingAmount = previousThawingAmount + thawedAmount; + account.thawEndTime = uint64(block.timestamp + THAWING_PERIOD); + + emit ThawInitiated( + buyer, seller, asset, account.thawingAmount, previousThawingAmount, account.thawEndTime, previousThawEndTime + ); + } + + /** + * @notice Internal function to withdraw funds that have completed thawing + * @dev This function will NOT revert if there are no funds ready to withdraw. + * It will simply return 0 if: + * - No funds are currently thawing (thawingAmount == 0) + * - The thaw period hasn't completed yet (block.timestamp < thawEndTime) + * The function automatically handles edge cases like collections during thaw period + * by capping the withdrawal to the actual balance if needed. + * If the account becomes empty after withdrawal, it is automatically cleaned up + * and removed from the buyer's escrow keys set. + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @return withdrawnAmount The actual amount withdrawn (0 if nothing was ready) + */ + function _withdraw(address buyer, address seller, address asset) internal returns (uint256 withdrawnAmount) { + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[buyer][seller][asset]; + + // Check if there's anything to withdraw + if (account.thawingAmount == 0 || block.timestamp < account.thawEndTime) { + return 0; // Nothing ready to withdraw + } + + withdrawnAmount = account.thawingAmount; + + // Ensure balance still covers the thawing amount (in case of collections during thaw) + if (withdrawnAmount > account.balance) { + withdrawnAmount = account.balance; + } + + // Update balance and clear thawing state + account.balance -= withdrawnAmount; + account.thawingAmount = 0; + account.thawEndTime = 0; + + // Transfer tokens to buyer + if (withdrawnAmount > 0) { + IERC20(asset).safeTransfer(buyer, withdrawnAmount); + emit Withdrawn(buyer, seller, asset, withdrawnAmount, account.balance); + } + + // Clean up if account is empty + if (account.balance == 0 && account.thawingAmount == 0) { + bytes32 key = keccak256(abi.encodePacked(seller, asset)); + $.buyerEscrowKeys[buyer].remove(key); + } + } + + /** + * @notice Internal function to calculate outstanding and collectable amounts + * @param voucher The voucher to check + * @param alreadyCollected Amount already collected for this voucher + * @return outstanding Total amount still owed on the voucher + * @return collectable Amount that can actually be collected now + */ + function _getOutstandingAndCollectableAmount(Voucher calldata voucher, uint256 alreadyCollected) + internal + view + returns (uint256 outstanding, uint256 collectable) + { + outstanding = 0; + collectable = 0; + + if (voucher.valueAggregate > alreadyCollected) { + outstanding = voucher.valueAggregate - alreadyCollected; + + MainStorage storage $ = _getMainStorage(); + EscrowAccount memory account = $.accounts[voucher.buyer][voucher.seller][voucher.asset]; + + // Full balance is available for collection (thawing doesn't block sellers) + collectable = outstanding > account.balance ? account.balance : outstanding; + } + } +} diff --git a/solidity/packages/deferred-escrow/src/IDeferredPaymentEscrow.sol b/solidity/packages/deferred-escrow/src/IDeferredPaymentEscrow.sol new file mode 100644 index 0000000000..e5c8a1d42a --- /dev/null +++ b/solidity/packages/deferred-escrow/src/IDeferredPaymentEscrow.sol @@ -0,0 +1,476 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; + +/** + * @title IDeferredPaymentEscrow + * @notice Interface for a multi-token escrow system supporting off-chain vouchers + * @dev Enables micropayments between buyers and sellers using EIP-712 signed vouchers + */ +interface IDeferredPaymentEscrow { + // ============ ERRORS ============ + + error InvalidAddress(address provided); + error InvalidAmount(uint256 provided); + error InvalidAsset(address provided); + error InvalidThawingPeriod(uint256 provided, uint256 maximum); + error InsufficientBalance(uint256 available, uint256 requested); + error NoThawingInProgress(address buyer, address seller, address asset); + error ThawingPeriodNotCompleted(uint256 currentTime, uint256 thawEndTime); + error InvalidEscrow(address provided, address expected); + error InvalidChainId(uint256 provided, uint256 expected); + error VoucherExpired(bytes32 voucherId, uint256 currentTime, uint256 expiry); + error InvalidSignature(bytes32 voucherId, address buyer); + error NoDepositsProvided(); + error NoVouchersProvided(); + error AuthorizationExpired(uint64 expiry, uint256 currentTime); + error NonceAlreadyUsed(bytes32 nonce); + error InvalidAuthorization(); + + // ============ STRUCTS ============ + + /** + * @notice Represents an escrow account for a specific buyer-seller-asset combination + * @param balance Current deposited balance available for payments + * @param thawingAmount Amount currently in the thawing process + * @param thawEndTime Timestamp when the thawing period completes + */ + struct EscrowAccount { + uint256 balance; + uint256 thawingAmount; + uint64 thawEndTime; + } + + /** + * @notice Represents a payment voucher with all required fields + * @param id Unique identifier for the voucher (unique per buyer-seller pair) + * @param buyer Address of the payment initiator + * @param seller Address of the payment recipient + * @param valueAggregate Total outstanding amount (monotonically increasing) + * @param asset ERC-20 token address + * @param timestamp Last aggregation timestamp + * @param nonce Incremented with each aggregation + * @param escrow Address of this escrow contract + * @param chainId Network chain ID + * @param expiry Expiration timestamp after which voucher cannot be collected + */ + struct Voucher { + bytes32 id; + address buyer; + address seller; + uint256 valueAggregate; + address asset; + uint64 timestamp; + uint256 nonce; + address escrow; + uint256 chainId; + uint64 expiry; + } + + /** + * @notice Input structure for batch deposits + * @param seller Address of the seller to deposit for + * @param amount Amount to deposit + */ + struct DepositInput { + address seller; + uint256 amount; + } + + /** + * @notice Signed voucher (Input structure for batch voucher collections) + * @param voucher The voucher to collect + * @param signature Buyer's signature for the voucher + * @param amount Amount to collect (0 means collect all available) + */ + struct SignedVoucher { + Voucher voucher; + bytes signature; + } + + /** + * @notice Authorization for depositing funds into escrow + * @param buyer Address of the buyer authorizing the deposit + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + * @param nonce Random bytes32 for replay protection + * @param expiry Expiration timestamp + */ + struct DepositAuthorization { + address buyer; + address seller; + address asset; + uint256 amount; + bytes32 nonce; + uint64 expiry; + } + + /** + * @notice Authorization for flushing a specific escrow + * @param buyer Address of the buyer authorizing the flush + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param nonce Random bytes32 for replay protection + * @param expiry Expiration timestamp + */ + struct FlushAuthorization { + address buyer; + address seller; + address asset; + bytes32 nonce; + uint64 expiry; + } + + /** + * @notice Authorization for flushing all escrows for a buyer + * @param buyer Address of the buyer authorizing the flush + * @param nonce Random bytes32 for replay protection + * @param expiry Expiration timestamp + */ + struct FlushAllAuthorization { + address buyer; + bytes32 nonce; + uint64 expiry; + } + + // ============ EVENTS ============ + + /** + * @notice Emitted when funds are deposited into an escrow account + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount deposited + * @param newBalance New total balance for the account + */ + event Deposited( + address indexed buyer, address indexed seller, address indexed asset, uint256 amount, uint256 newBalance + ); + + /** + * @notice Emitted when a thawing process is initiated or increased + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param newThawingAmount New total amount being thawed + * @param previousThawingAmount Previous amount that was thawing (0 if new thaw) + * @param newThawEndTime New timestamp when thawing completes + * @param previousThawEndTime Previous thaw end time (0 if new thaw) + */ + event ThawInitiated( + address indexed buyer, + address indexed seller, + address indexed asset, + uint256 newThawingAmount, + uint256 previousThawingAmount, + uint256 newThawEndTime, + uint256 previousThawEndTime + ); + + /** + * @notice Emitted when a thawing process is cancelled + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount that was being thawed + */ + event ThawCancelled(address indexed buyer, address indexed seller, address indexed asset, uint256 amount); + + /** + * @notice Emitted when funds are withdrawn from an escrow account + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount withdrawn + * @param remainingBalance Remaining balance after withdrawal + */ + event Withdrawn( + address indexed buyer, address indexed seller, address indexed asset, uint256 amount, uint256 remainingBalance + ); + + /** + * @notice Emitted when a voucher is collected + * @param voucherId Unique identifier of the voucher + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount collected + * @param totalCollected Total amount collected for this voucher + */ + event VoucherCollected( + bytes32 indexed voucherId, + address indexed buyer, + address indexed seller, + address asset, + uint256 amount, + uint256 totalCollected + ); + + /** + * @notice Emitted when a voucher collection is skipped because it was already fully collected + * @param voucherId Unique identifier of the voucher + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param totalCollected Total amount already collected for this voucher + */ + event VoucherAlreadyCollected( + bytes32 indexed voucherId, address indexed buyer, address indexed seller, address asset, uint256 totalCollected + ); + + /** + * @notice Emitted when a voucher has outstanding amount but no collectable balance + * @param voucherId Unique identifier of the voucher + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param outstanding Amount still owed on the voucher + * @param alreadyCollected Amount already collected for this voucher + */ + event VoucherNoCollectableBalance( + bytes32 indexed voucherId, + address indexed buyer, + address indexed seller, + address asset, + uint256 outstanding, + uint256 alreadyCollected + ); + + /** + * @notice Emitted when a deposit is made using authorization + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount deposited + * @param nonce Nonce used for the authorization + */ + event DepositAuthorized( + address indexed buyer, address indexed seller, address indexed asset, uint256 amount, bytes32 nonce + ); + + /** + * @notice Emitted when a flush is initiated or completed using authorization + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param nonce Nonce used for the authorization + * @param thawing True if thawing was initiated, false if withdrawal completed + */ + event FlushAuthorized( + address indexed buyer, address indexed seller, address indexed asset, bytes32 nonce, bool thawing + ); + + /** + * @notice Emitted when all escrows are flushed using authorization + * @param buyer Address of the buyer + * @param nonce Nonce used for the authorization + * @param accountsFlushed Number of accounts affected + */ + event FlushAllAuthorized(address indexed buyer, bytes32 nonce, uint256 accountsFlushed); + + // ============ DEPOSIT FUNCTIONS ============ + + /** + * @notice Deposit tokens into escrow for a specific seller and asset + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + */ + function deposit(address seller, address asset, uint256 amount) external; + + /** + * @notice Deposit tokens into escrow on behalf of a buyer + * @param buyer Address of the buyer who will own the escrow + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + */ + function depositTo(address buyer, address seller, address asset, uint256 amount) external; + + /** + * @notice Deposit tokens for multiple sellers with a single asset in a single transaction + * @param asset ERC-20 token address + * @param deposits Array of deposit inputs + */ + function depositMany(address asset, DepositInput[] calldata deposits) external; + + /** + * @notice Deposit tokens using EIP-712 signed authorization + * @param auth The deposit authorization struct + * @param signature Buyer's signature for the authorization + */ + function depositWithAuthorization(DepositAuthorization calldata auth, bytes calldata signature) external; + + // ============ WITHDRAWAL FUNCTIONS ============ + + /** + * @notice Initiate withdrawal process (starts thawing period) + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to withdraw + */ + function thaw(address seller, address asset, uint256 amount) external; + + /** + * @notice Cancel an ongoing thawing process + * @param seller Address of the seller + * @param asset ERC-20 token address + */ + function cancelThaw(address seller, address asset) external; + + /** + * @notice Complete withdrawal after thawing period + * @param seller Address of the seller + * @param asset ERC-20 token address + */ + function withdraw(address seller, address asset) external; + + /** + * @notice Initiate or complete flush using EIP-712 signed authorization + * @param auth The flush authorization struct + * @param signature Buyer's signature for the authorization + */ + function flushWithAuthorization(FlushAuthorization calldata auth, bytes calldata signature) external; + + /** + * @notice Flush all escrows for a buyer using EIP-712 signed authorization + * @param auth The flush all authorization struct + * @param signature Buyer's signature for the authorization + */ + function flushAllWithAuthorization(FlushAllAuthorization calldata auth, bytes calldata signature) external; + + // ============ COLLECTION FUNCTIONS ============ + + /** + * @notice Collect a single voucher (partial or full) + * @param voucher The voucher to collect + * @param signature Buyer's signature for the voucher + */ + function collect(Voucher calldata voucher, bytes calldata signature) external; + + /** + * @notice Collect multiple vouchers in a single transaction + * @param vouchers Array of signed vouchers + */ + function collectMany(SignedVoucher[] calldata vouchers) external; + + // ============ VIEW FUNCTIONS ============ + + /** + * @notice Get escrow account details for a buyer-seller-asset combination + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @return EscrowAccount struct with balance, thawing amount, and thaw end time + */ + function getAccount(address buyer, address seller, address asset) external view returns (EscrowAccount memory); + + /** + * @notice Get the amount already collected for a specific voucher + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param voucherId Unique identifier of the voucher + * @return Amount already collected + */ + function getVoucherCollected(address buyer, address seller, address asset, bytes32 voucherId) + external + view + returns (uint256); + + /** + * @notice Calculate the outstanding and collectable amounts for a voucher + * @param voucher The voucher to check + * @return outstanding Total amount still owed on the voucher + * @return collectable Amount that can actually be collected now (considering available balance) + */ + function getOutstandingAndCollectableAmount(Voucher calldata voucher) + external + view + returns (uint256 outstanding, uint256 collectable); + + /** + * @notice Validate a voucher signature + * @param voucher The voucher to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isVoucherSignatureValid(Voucher calldata voucher, bytes calldata signature) external view returns (bool); + + /** + * @notice Validate a deposit authorization signature + * @param auth The deposit authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isDepositAuthorizationValid(DepositAuthorization calldata auth, bytes calldata signature) + external + view + returns (bool); + + /** + * @notice Validate a flush authorization signature + * @param auth The flush authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isFlushAuthorizationValid(FlushAuthorization calldata auth, bytes calldata signature) + external + view + returns (bool); + + /** + * @notice Validate a flush all authorization signature + * @param auth The flush all authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isFlushAllAuthorizationValid(FlushAllAuthorization calldata auth, bytes calldata signature) + external + view + returns (bool); + + /** + * @notice Get the current thawing period + * @return Thawing period in seconds + */ + function THAWING_PERIOD() external view returns (uint256); + + /** + * @notice Get the EIP-712 domain separator + * @return Domain separator hash + */ + function DOMAIN_SEPARATOR() external view returns (bytes32); + + // ============ CONSTANTS ============ + + /** + * @notice Maximum allowed thawing period + * @return Maximum thawing period in seconds (30 days) + */ + function MAX_THAWING_PERIOD() external view returns (uint256); + + /** + * @notice EIP-712 type hash for voucher structure + * @return Type hash for voucher + */ + function VOUCHER_TYPEHASH() external view returns (bytes32); + + /** + * @notice EIP-712 type hash for deposit authorization structure + * @return Type hash for deposit authorization + */ + function DEPOSIT_AUTHORIZATION_TYPEHASH() external view returns (bytes32); + + /** + * @notice EIP-712 type hash for flush authorization structure + * @return Type hash for flush authorization + */ + function FLUSH_AUTHORIZATION_TYPEHASH() external view returns (bytes32); + + /** + * @notice EIP-712 type hash for flush all authorization structure + * @return Type hash for flush all authorization + */ + function FLUSH_ALL_AUTHORIZATION_TYPEHASH() external view returns (bytes32); +} diff --git a/solidity/packages/deferred-escrow/src/libraries/EscrowSignatureLib.sol b/solidity/packages/deferred-escrow/src/libraries/EscrowSignatureLib.sol new file mode 100644 index 0000000000..892a4bfdb0 --- /dev/null +++ b/solidity/packages/deferred-escrow/src/libraries/EscrowSignatureLib.sol @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {SignatureChecker} from "../../lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol"; +import {IDeferredPaymentEscrow} from "../IDeferredPaymentEscrow.sol"; + +/** + * @title EscrowSignatureLib + * @notice Library for escrow-related signature validation using EIP-712 + */ +library EscrowSignatureLib { + /// @notice EIP-712 type hash for voucher structure + bytes32 public constant VOUCHER_TYPEHASH = keccak256( + "Voucher(bytes32 id,address buyer,address seller,uint256 valueAggregate,address asset,uint64 timestamp,uint256 nonce,address escrow,uint256 chainId,uint64 expiry)" + ); + + /// @notice EIP-712 type hash for deposit authorization + bytes32 public constant DEPOSIT_AUTHORIZATION_TYPEHASH = keccak256( + "DepositAuthorization(address buyer,address seller,address asset,uint256 amount,bytes32 nonce,uint64 expiry)" + ); + + /// @notice EIP-712 type hash for flush authorization + bytes32 public constant FLUSH_AUTHORIZATION_TYPEHASH = + keccak256("FlushAuthorization(address buyer,address seller,address asset,bytes32 nonce,uint64 expiry)"); + + /// @notice EIP-712 type hash for flush all authorization + bytes32 public constant FLUSH_ALL_AUTHORIZATION_TYPEHASH = + keccak256("FlushAllAuthorization(address buyer,bytes32 nonce,uint64 expiry)"); + + /** + * @notice Validate voucher signature + * @param voucher The voucher to validate + * @param signature The signature to validate + * @param domainSeparator The EIP-712 domain separator + * @return True if signature is valid + */ + function isVoucherSignatureValid( + IDeferredPaymentEscrow.Voucher calldata voucher, + bytes calldata signature, + bytes32 domainSeparator + ) external view returns (bool) { + bytes32 structHash = keccak256( + abi.encode( + VOUCHER_TYPEHASH, + voucher.id, + voucher.buyer, + voucher.seller, + voucher.valueAggregate, + voucher.asset, + voucher.timestamp, + voucher.nonce, + voucher.escrow, + voucher.chainId, + voucher.expiry + ) + ); + + bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); + + // Use OpenZeppelin's SignatureChecker for both EOA and ERC-1271 + return SignatureChecker.isValidSignatureNow(voucher.buyer, digest, signature); + } + + /** + * @notice Validate deposit authorization signature + * @param auth The deposit authorization to validate + * @param signature The signature to validate + * @param domainSeparator The EIP-712 domain separator + * @return True if signature is valid + */ + function isDepositAuthorizationValid( + IDeferredPaymentEscrow.DepositAuthorization calldata auth, + bytes calldata signature, + bytes32 domainSeparator + ) external view returns (bool) { + bytes32 structHash = keccak256( + abi.encode( + DEPOSIT_AUTHORIZATION_TYPEHASH, + auth.buyer, + auth.seller, + auth.asset, + auth.amount, + auth.nonce, + auth.expiry + ) + ); + + bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); + + // Use OpenZeppelin's SignatureChecker for both EOA and ERC-1271 + return SignatureChecker.isValidSignatureNow(auth.buyer, digest, signature); + } + + /** + * @notice Validate flush authorization signature + * @param auth The flush authorization to validate + * @param signature The signature to validate + * @param domainSeparator The EIP-712 domain separator + * @return True if signature is valid + */ + function isFlushAuthorizationValid( + IDeferredPaymentEscrow.FlushAuthorization calldata auth, + bytes calldata signature, + bytes32 domainSeparator + ) external view returns (bool) { + bytes32 structHash = keccak256( + abi.encode(FLUSH_AUTHORIZATION_TYPEHASH, auth.buyer, auth.seller, auth.asset, auth.nonce, auth.expiry) + ); + + bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); + + // Use OpenZeppelin's SignatureChecker for both EOA and ERC-1271 + return SignatureChecker.isValidSignatureNow(auth.buyer, digest, signature); + } + + /** + * @notice Validate flush all authorization signature + * @param auth The flush all authorization to validate + * @param signature The signature to validate + * @param domainSeparator The EIP-712 domain separator + * @return True if signature is valid + */ + function isFlushAllAuthorizationValid( + IDeferredPaymentEscrow.FlushAllAuthorization calldata auth, + bytes calldata signature, + bytes32 domainSeparator + ) external view returns (bool) { + bytes32 structHash = keccak256( + abi.encode(FLUSH_ALL_AUTHORIZATION_TYPEHASH, auth.buyer, auth.nonce, auth.expiry) + ); + + bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); + + // Use OpenZeppelin's SignatureChecker for both EOA and ERC-1271 + return SignatureChecker.isValidSignatureNow(auth.buyer, digest, signature); + } +} diff --git a/solidity/packages/deferred-escrow/test/BaseTest.sol b/solidity/packages/deferred-escrow/test/BaseTest.sol new file mode 100644 index 0000000000..75e4a36cef --- /dev/null +++ b/solidity/packages/deferred-escrow/test/BaseTest.sol @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {Test} from "forge-std/Test.sol"; +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; + +import {DeferredPaymentEscrow} from "../src/DeferredPaymentEscrow.sol"; +import {IDeferredPaymentEscrow} from "../src/IDeferredPaymentEscrow.sol"; +import {MockERC20} from "./mocks/MockERC20.sol"; +import {MockERC1271} from "./mocks/MockERC1271.sol"; +import {MockNonStandardERC20} from "./mocks/MockNonStandardERC20.sol"; + +contract BaseTest is Test { + using ECDSA for bytes32; + + DeferredPaymentEscrow public escrow; + MockERC20 public usdc; + MockERC20 public usdt; + MockERC1271 public smartWallet; + + address public buyer = makeAddr("buyer"); + address public seller = makeAddr("seller"); + + uint256 public buyerPrivateKey = 0x12345; + address public buyerFromPrivateKey; + + uint256 public constant THAWING_PERIOD = 7 days; + uint256 public constant INITIAL_BALANCE = 1000000e18; + + // Test voucher data + bytes32 public constant VOUCHER_ID = keccak256("test-voucher-1"); + uint256 public constant VOUCHER_VALUE = 1000e18; + uint64 public voucherTimestamp; + uint64 public voucherExpiry; + + // ============ EVENTS ============ + + event Deposited( + address indexed buyer, address indexed seller, address indexed asset, uint256 amount, uint256 newBalance + ); + + event ThawInitiated( + address indexed buyer, + address indexed seller, + address indexed asset, + uint256 newThawingAmount, + uint256 previousThawingAmount, + uint256 newThawEndTime, + uint256 previousThawEndTime + ); + + event VoucherCollected( + bytes32 indexed voucherId, + address indexed buyer, + address indexed seller, + address asset, + uint256 amount, + uint256 totalCollected + ); + + event VoucherAlreadyCollected( + bytes32 indexed voucherId, address indexed buyer, address indexed seller, address asset, uint256 totalCollected + ); + + event VoucherNoCollectableBalance( + bytes32 indexed voucherId, + address indexed buyer, + address indexed seller, + address asset, + uint256 outstanding, + uint256 alreadyCollected + ); + + event DepositAuthorized( + address indexed buyer, address indexed seller, address indexed asset, uint256 amount, bytes32 nonce + ); + + event FlushAuthorized( + address indexed buyer, address indexed seller, address indexed asset, bytes32 nonce, bool thawing + ); + + event FlushAllAuthorized(address indexed buyer, bytes32 nonce, uint256 accountsFlushed); + + event Withdrawn( + address indexed buyer, address indexed seller, address indexed asset, uint256 amount, uint256 remainingBalance + ); + + function setUp() public virtual { + buyerFromPrivateKey = vm.addr(buyerPrivateKey); + voucherTimestamp = uint64(block.timestamp); + voucherExpiry = uint64(block.timestamp + 30 days); + + // Deploy mock tokens + usdc = new MockERC20("USD Coin", "USDC", 6); + usdt = new MockERC20("Tether USD", "USDT", 6); + smartWallet = new MockERC1271(); + + // Deploy escrow directly with constructor + escrow = new DeferredPaymentEscrow(THAWING_PERIOD); + + // Mint tokens to test accounts + usdc.mint(buyer, INITIAL_BALANCE); + usdc.mint(buyerFromPrivateKey, INITIAL_BALANCE); + usdt.mint(buyer, INITIAL_BALANCE); + usdt.mint(buyerFromPrivateKey, INITIAL_BALANCE); + + // Approve escrow to spend tokens + vm.startPrank(buyer); + usdc.approve(address(escrow), type(uint256).max); + usdt.approve(address(escrow), type(uint256).max); + vm.stopPrank(); + + vm.startPrank(buyerFromPrivateKey); + usdc.approve(address(escrow), type(uint256).max); + usdt.approve(address(escrow), type(uint256).max); + vm.stopPrank(); + } + + // ============ HELPER FUNCTIONS ============ + + function createVoucher( + bytes32 id, + address buyerAddr, + address sellerAddr, + uint256 value, + address asset, + uint64 timestamp, + uint256 nonce, + uint64 expiry + ) internal view returns (IDeferredPaymentEscrow.Voucher memory) { + return IDeferredPaymentEscrow.Voucher({ + id: id, + buyer: buyerAddr, + seller: sellerAddr, + valueAggregate: value, + asset: asset, + timestamp: timestamp, + nonce: nonce, + escrow: address(escrow), + chainId: block.chainid, + expiry: expiry + }); + } + + function signVoucher(IDeferredPaymentEscrow.Voucher memory voucher, uint256 privateKey) + internal + view + returns (bytes memory) + { + bytes32 structHash = keccak256( + abi.encode( + escrow.VOUCHER_TYPEHASH(), + voucher.id, + voucher.buyer, + voucher.seller, + voucher.valueAggregate, + voucher.asset, + voucher.timestamp, + voucher.nonce, + voucher.escrow, + voucher.chainId, + voucher.expiry + ) + ); + + bytes32 digest = keccak256(abi.encodePacked("\x19\x01", escrow.DOMAIN_SEPARATOR(), structHash)); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + return abi.encodePacked(r, s, v); + } + + function signFlushAuthorization(IDeferredPaymentEscrow.FlushAuthorization memory auth, uint256 privateKey) + internal + view + returns (bytes memory) + { + bytes32 structHash = keccak256( + abi.encode( + keccak256("FlushAuthorization(address buyer,address seller,address asset,bytes32 nonce,uint64 expiry)"), + auth.buyer, + auth.seller, + auth.asset, + auth.nonce, + auth.expiry + ) + ); + + bytes32 digest = keccak256(abi.encodePacked("\x19\x01", escrow.DOMAIN_SEPARATOR(), structHash)); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + return abi.encodePacked(r, s, v); + } + + function signFlushAllAuthorization(IDeferredPaymentEscrow.FlushAllAuthorization memory auth, uint256 privateKey) + internal + view + returns (bytes memory) + { + bytes32 structHash = keccak256( + abi.encode( + keccak256("FlushAllAuthorization(address buyer,bytes32 nonce,uint64 expiry)"), + auth.buyer, + auth.nonce, + auth.expiry + ) + ); + + bytes32 digest = keccak256(abi.encodePacked("\x19\x01", escrow.DOMAIN_SEPARATOR(), structHash)); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + return abi.encodePacked(r, s, v); + } + + function signDepositAuthorization(IDeferredPaymentEscrow.DepositAuthorization memory auth, uint256 privateKey) + internal + view + returns (bytes memory) + { + bytes32 structHash = keccak256( + abi.encode( + keccak256( + "DepositAuthorization(address buyer,address seller,address asset,uint256 amount,bytes32 nonce,uint64 expiry)" + ), + auth.buyer, + auth.seller, + auth.asset, + auth.amount, + auth.nonce, + auth.expiry + ) + ); + + bytes32 digest = keccak256(abi.encodePacked("\x19\x01", escrow.DOMAIN_SEPARATOR(), structHash)); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + return abi.encodePacked(r, s, v); + } +} diff --git a/solidity/packages/deferred-escrow/test/DepositTest.t.sol b/solidity/packages/deferred-escrow/test/DepositTest.t.sol new file mode 100644 index 0000000000..b86482d747 --- /dev/null +++ b/solidity/packages/deferred-escrow/test/DepositTest.t.sol @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {BaseTest} from "./BaseTest.sol"; +import {DeferredPaymentEscrow} from "../src/DeferredPaymentEscrow.sol"; +import {IDeferredPaymentEscrow} from "../src/IDeferredPaymentEscrow.sol"; + +contract DepositTest is BaseTest { + // ============ INITIALIZATION TESTS ============ + + function test_Initialize() public { + assertEq(escrow.THAWING_PERIOD(), THAWING_PERIOD); + } + + function test_Initialize_InvalidThawingPeriod() public { + uint256 invalidPeriod = 31 days; // Greater than MAX_THAWING_PERIOD (30 days) + vm.expectRevert( + abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidThawingPeriod.selector, invalidPeriod, 30 days) + ); + new DeferredPaymentEscrow(invalidPeriod); + } + + // ============ DEPOSIT TESTS ============ + + function test_Deposit() public { + uint256 amount = 1000e6; + + vm.expectEmit(true, true, true, true); + emit Deposited(buyer, seller, address(usdc), amount, amount); + + vm.prank(buyer); + escrow.deposit(seller, address(usdc), amount); + + IDeferredPaymentEscrow.EscrowAccount memory account = escrow.getAccount(buyer, seller, address(usdc)); + assertEq(account.balance, amount); + assertEq(account.thawingAmount, 0); + assertEq(account.thawEndTime, 0); + assertEq(usdc.balanceOf(address(escrow)), amount); + } + + function test_Deposit_InvalidSeller() public { + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAddress.selector, address(0))); + escrow.deposit(address(0), address(usdc), 1000e6); + } + + function test_Deposit_InvalidAsset() public { + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAsset.selector, address(0))); + escrow.deposit(seller, address(0), 1000e6); + } + + function test_Deposit_ZeroAmount() public { + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAmount.selector, 0)); + escrow.deposit(seller, address(usdc), 0); + } + + function test_DepositMany() public { + address seller2 = makeAddr("seller2"); + uint256 amount1 = 1000e6; + uint256 amount2 = 2000e6; + uint256 totalAmount = amount1 + amount2; + + IDeferredPaymentEscrow.DepositInput[] memory deposits = new IDeferredPaymentEscrow.DepositInput[](2); + deposits[0] = IDeferredPaymentEscrow.DepositInput({seller: seller, amount: amount1}); + deposits[1] = IDeferredPaymentEscrow.DepositInput({seller: seller2, amount: amount2}); + + vm.expectEmit(true, true, true, true); + emit Deposited(buyer, seller, address(usdc), amount1, amount1); + vm.expectEmit(true, true, true, true); + emit Deposited(buyer, seller2, address(usdc), amount2, amount2); + + vm.prank(buyer); + escrow.depositMany(address(usdc), deposits); + + assertEq(escrow.getAccount(buyer, seller, address(usdc)).balance, amount1); + assertEq(escrow.getAccount(buyer, seller2, address(usdc)).balance, amount2); + assertEq(usdc.balanceOf(address(escrow)), totalAmount); + } + + function test_DepositMany_InvalidAsset() public { + IDeferredPaymentEscrow.DepositInput[] memory deposits = new IDeferredPaymentEscrow.DepositInput[](1); + deposits[0] = IDeferredPaymentEscrow.DepositInput({seller: seller, amount: 1000e6}); + + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAsset.selector, address(0))); + escrow.depositMany(address(0), deposits); + } + + function test_DepositMany_EmptyDeposits() public { + IDeferredPaymentEscrow.DepositInput[] memory deposits = new IDeferredPaymentEscrow.DepositInput[](0); + + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.NoDepositsProvided.selector)); + escrow.depositMany(address(usdc), deposits); + } + + function test_DepositTo() public { + uint256 amount = 1000e6; + address beneficiary = address(0x1234); + + usdc.mint(address(this), amount); + usdc.approve(address(escrow), amount); + + // Deposit on behalf of beneficiary + vm.expectEmit(true, true, true, true); + emit Deposited(beneficiary, seller, address(usdc), amount, amount); + + escrow.depositTo(beneficiary, seller, address(usdc), amount); + + // Check that beneficiary owns the escrow, not msg.sender + assertEq(escrow.getAccount(beneficiary, seller, address(usdc)).balance, amount); + assertEq(escrow.getAccount(address(this), seller, address(usdc)).balance, 0); + assertEq(usdc.balanceOf(address(escrow)), amount); + } + + function test_DepositTo_InvalidBuyer() public { + uint256 amount = 1000e6; + + usdc.mint(address(this), amount); + usdc.approve(address(escrow), amount); + + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAddress.selector, address(0))); + escrow.depositTo(address(0), seller, address(usdc), amount); + } + + // ============ DEPOSIT AUTHORIZATION TESTS ============ + + function test_DepositWithAuthorization_Success() public { + uint256 depositAmount = 1000e6; + bytes32 nonce = keccak256("test-nonce-1"); + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Create authorization + IDeferredPaymentEscrow.DepositAuthorization memory auth = IDeferredPaymentEscrow.DepositAuthorization({ + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + amount: depositAmount, + nonce: nonce, + expiry: expiry + }); + + // Sign authorization + bytes memory signature = signDepositAuthorization(auth, buyerPrivateKey); + + // Approve escrow + vm.prank(buyerFromPrivateKey); + usdc.approve(address(escrow), depositAmount); + + // Execute deposit + vm.expectEmit(true, true, true, true); + emit Deposited(buyerFromPrivateKey, seller, address(usdc), depositAmount, depositAmount); + vm.expectEmit(true, true, true, true); + emit DepositAuthorized(buyerFromPrivateKey, seller, address(usdc), depositAmount, nonce); + + escrow.depositWithAuthorization(auth, signature); + + // Verify state + IDeferredPaymentEscrow.EscrowAccount memory account = + escrow.getAccount(buyerFromPrivateKey, seller, address(usdc)); + assertEq(account.balance, depositAmount); + } + + function test_DepositWithAuthorization_ExpiredReverts() public { + uint256 depositAmount = 1000e6; + bytes32 nonce = keccak256("test-nonce-2"); + uint64 expiry = uint64(block.timestamp - 1); // Already expired + + IDeferredPaymentEscrow.DepositAuthorization memory auth = IDeferredPaymentEscrow.DepositAuthorization({ + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + amount: depositAmount, + nonce: nonce, + expiry: expiry + }); + + // Sign authorization + bytes memory signature = signDepositAuthorization(auth, buyerPrivateKey); + + vm.expectRevert( + abi.encodeWithSelector(IDeferredPaymentEscrow.AuthorizationExpired.selector, expiry, block.timestamp) + ); + escrow.depositWithAuthorization(auth, signature); + } + + function test_DepositWithAuthorization_NonceReplayReverts() public { + uint256 depositAmount = 1000e6; + bytes32 nonce = keccak256("test-nonce-3"); + uint64 expiry = uint64(block.timestamp + 1 hours); + + IDeferredPaymentEscrow.DepositAuthorization memory auth = IDeferredPaymentEscrow.DepositAuthorization({ + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + amount: depositAmount, + nonce: nonce, + expiry: expiry + }); + + // Sign authorization + bytes memory signature = signDepositAuthorization(auth, buyerPrivateKey); + + // Approve and execute first deposit + vm.prank(buyerFromPrivateKey); + usdc.approve(address(escrow), depositAmount * 2); + escrow.depositWithAuthorization(auth, signature); + + // Try to replay the same authorization + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.NonceAlreadyUsed.selector, nonce)); + escrow.depositWithAuthorization(auth, signature); + } + + function test_DepositWithAuthorization_InvalidSignatureReverts() public { + uint256 depositAmount = 1000e6; + bytes32 nonce = keccak256("test-nonce-4"); + uint64 expiry = uint64(block.timestamp + 1 hours); + + IDeferredPaymentEscrow.DepositAuthorization memory auth = IDeferredPaymentEscrow.DepositAuthorization({ + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + amount: depositAmount, + nonce: nonce, + expiry: expiry + }); + + // Sign with wrong private key + uint256 wrongPrivateKey = 0x54321; + bytes memory signature = signDepositAuthorization(auth, wrongPrivateKey); + + vm.expectRevert(IDeferredPaymentEscrow.InvalidAuthorization.selector); + escrow.depositWithAuthorization(auth, signature); + } + + function test_DepositWithAuthorization_SmartWalletSignature() public { + uint256 depositAmount = 1000e6; + bytes32 nonce = keccak256("test-nonce-5"); + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Fund smart wallet + usdc.mint(address(smartWallet), depositAmount); + vm.prank(address(smartWallet)); + usdc.approve(address(escrow), depositAmount); + + IDeferredPaymentEscrow.DepositAuthorization memory auth = IDeferredPaymentEscrow.DepositAuthorization({ + buyer: address(smartWallet), + seller: seller, + asset: address(usdc), + amount: depositAmount, + nonce: nonce, + expiry: expiry + }); + + // Create digest for smart wallet using helper function + bytes memory signature = signDepositAuthorization(auth, buyerPrivateKey); + bytes32 structHash = keccak256( + abi.encode( + keccak256( + "DepositAuthorization(address buyer,address seller,address asset,uint256 amount,bytes32 nonce,uint64 expiry)" + ), + auth.buyer, + auth.seller, + auth.asset, + auth.amount, + auth.nonce, + auth.expiry + ) + ); + bytes32 digest = keccak256(abi.encodePacked("\x19\x01", escrow.DOMAIN_SEPARATOR(), structHash)); + + // Set the smart wallet to accept this digest + smartWallet.setValidHash(digest, true); + signature = hex"1234"; // Dummy signature, smart wallet will validate + + // Execute deposit + escrow.depositWithAuthorization(auth, signature); + + // Verify state + IDeferredPaymentEscrow.EscrowAccount memory account = + escrow.getAccount(address(smartWallet), seller, address(usdc)); + assertEq(account.balance, depositAmount); + } +} diff --git a/solidity/packages/deferred-escrow/test/ThawWithdrawTest.t.sol b/solidity/packages/deferred-escrow/test/ThawWithdrawTest.t.sol new file mode 100644 index 0000000000..058ce3c7b0 --- /dev/null +++ b/solidity/packages/deferred-escrow/test/ThawWithdrawTest.t.sol @@ -0,0 +1,570 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {BaseTest} from "./BaseTest.sol"; +import {IDeferredPaymentEscrow} from "../src/IDeferredPaymentEscrow.sol"; + +contract ThawWithdrawTest is BaseTest { + // ============ THAWING TESTS ============ + + function test_Thaw() public { + uint256 depositAmount = 1000e6; + uint256 thawAmount = 500e6; + + // First deposit + vm.prank(buyer); + escrow.deposit(seller, address(usdc), depositAmount); + + // Then thaw + vm.expectEmit(true, true, true, true); + emit ThawInitiated( + buyer, + seller, + address(usdc), + thawAmount, + 0, // previousThawingAmount + uint256(block.timestamp + THAWING_PERIOD), + 0 // previousThawEndTime + ); + + vm.prank(buyer); + escrow.thaw(seller, address(usdc), thawAmount); + + IDeferredPaymentEscrow.EscrowAccount memory account = escrow.getAccount(buyer, seller, address(usdc)); + assertEq(account.balance, depositAmount); // Balance unchanged in new model + assertEq(account.thawingAmount, thawAmount); + assertEq(account.thawEndTime, block.timestamp + THAWING_PERIOD); + } + + function test_Thaw_InsufficientBalance() public { + uint256 depositAmount = 1000e6; + uint256 thawAmount = 2000e6; + + vm.prank(buyer); + escrow.deposit(seller, address(usdc), depositAmount); + + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InsufficientBalance.selector, 1000e6, 2000e6)); + escrow.thaw(seller, address(usdc), thawAmount); + } + + function test_Thaw_IncreaseAmount() public { + uint256 depositAmount = 1000e6; + uint256 firstThawAmount = 300e6; + uint256 additionalThawAmount = 200e6; + uint256 totalThawAmount = 500e6; + + vm.prank(buyer); + escrow.deposit(seller, address(usdc), depositAmount); + + // First thaw + vm.prank(buyer); + escrow.thaw(seller, address(usdc), firstThawAmount); + + uint256 firstThawEndTime = block.timestamp + THAWING_PERIOD; + + // Move forward in time + vm.warp(block.timestamp + 100); + + // Second thaw should increase amount and reset timer + vm.expectEmit(true, true, true, true); + emit ThawInitiated( + buyer, + seller, + address(usdc), + totalThawAmount, + firstThawAmount, + uint256(vm.getBlockTimestamp() + THAWING_PERIOD), // Use vm.getBlockTimestamp() with --via-ir + firstThawEndTime + ); + + vm.prank(buyer); + escrow.thaw(seller, address(usdc), additionalThawAmount); + + IDeferredPaymentEscrow.EscrowAccount memory account = escrow.getAccount(buyer, seller, address(usdc)); + assertEq(account.balance, depositAmount); + assertEq(account.thawingAmount, totalThawAmount); + assertEq(account.thawEndTime, 101 + THAWING_PERIOD); // Timer reset after warp to timestamp 101 + } + + function test_Thaw_IncreaseAmount_InsufficientBalance() public { + uint256 depositAmount = 1000e6; + uint256 firstThawAmount = 700e6; + uint256 additionalThawAmount = 400e6; // Would total 1100e6, exceeding balance + + vm.prank(buyer); + escrow.deposit(seller, address(usdc), depositAmount); + + // First thaw + vm.prank(buyer); + escrow.thaw(seller, address(usdc), firstThawAmount); + + // Second thaw should revert due to insufficient balance + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InsufficientBalance.selector, 1000e6, 1100e6)); + escrow.thaw(seller, address(usdc), additionalThawAmount); + } + + function test_CancelThaw() public { + uint256 depositAmount = 1000e6; + uint256 thawAmount = 500e6; + + vm.prank(buyer); + escrow.deposit(seller, address(usdc), depositAmount); + + vm.prank(buyer); + escrow.thaw(seller, address(usdc), thawAmount); + + vm.prank(buyer); + escrow.cancelThaw(seller, address(usdc)); + + IDeferredPaymentEscrow.EscrowAccount memory account = escrow.getAccount(buyer, seller, address(usdc)); + assertEq(account.balance, depositAmount); + assertEq(account.thawingAmount, 0); + assertEq(account.thawEndTime, 0); + } + + function test_Withdraw() public { + uint256 depositAmount = 1000e6; + uint256 thawAmount = 500e6; + + vm.prank(buyer); + escrow.deposit(seller, address(usdc), depositAmount); + + vm.prank(buyer); + escrow.thaw(seller, address(usdc), thawAmount); + + // Fast forward past thawing period + vm.warp(block.timestamp + THAWING_PERIOD + 1); + + uint256 balanceBefore = usdc.balanceOf(buyer); + + vm.prank(buyer); + escrow.withdraw(seller, address(usdc)); + + assertEq(usdc.balanceOf(buyer), balanceBefore + thawAmount); + + IDeferredPaymentEscrow.EscrowAccount memory account = escrow.getAccount(buyer, seller, address(usdc)); + assertEq(account.balance, depositAmount - thawAmount); + assertEq(account.thawingAmount, 0); + assertEq(account.thawEndTime, 0); + } + + function test_Withdraw_ThawingNotCompleted() public { + uint256 depositAmount = 1000e6; + uint256 thawAmount = 500e6; + + vm.prank(buyer); + escrow.deposit(seller, address(usdc), depositAmount); + + vm.prank(buyer); + escrow.thaw(seller, address(usdc), thawAmount); + + uint256 thawEndTime = block.timestamp + THAWING_PERIOD; + + // Try to withdraw before thawing period completes + vm.prank(buyer); + vm.expectRevert( + abi.encodeWithSelector( + IDeferredPaymentEscrow.ThawingPeriodNotCompleted.selector, block.timestamp, thawEndTime + ) + ); + escrow.withdraw(seller, address(usdc)); + } + + // ============ INPUT VALIDATION TESTS ============ + + function test_Thaw_InvalidSeller() public { + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAddress.selector, address(0))); + escrow.thaw(address(0), address(usdc), 1000e6); + } + + function test_Thaw_InvalidAsset() public { + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAsset.selector, address(0))); + escrow.thaw(seller, address(0), 1000e6); + } + + function test_Thaw_ZeroAmount() public { + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAmount.selector, 0)); + escrow.thaw(seller, address(usdc), 0); + } + + function test_CancelThaw_InvalidSeller() public { + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAddress.selector, address(0))); + escrow.cancelThaw(address(0), address(usdc)); + } + + function test_CancelThaw_InvalidAsset() public { + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAsset.selector, address(0))); + escrow.cancelThaw(seller, address(0)); + } + + function test_Withdraw_InvalidSeller() public { + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAddress.selector, address(0))); + escrow.withdraw(address(0), address(usdc)); + } + + function test_Withdraw_InvalidAsset() public { + vm.prank(buyer); + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAsset.selector, address(0))); + escrow.withdraw(seller, address(0)); + } + + // ============ FLUSH AUTHORIZATION TESTS ============ + + function test_FlushWithAuthorization_WithdrawReady() public { + uint256 depositAmount = 1000e6; + bytes32 nonce = keccak256("flush-nonce-1"); + + // Setup: deposit and thaw funds using buyerFromPrivateKey + vm.startPrank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + escrow.thaw(seller, address(usdc), depositAmount); + vm.stopPrank(); + + // Warp to after thawing period + vm.warp(block.timestamp + THAWING_PERIOD + 1); + + // Set expiry AFTER warping to avoid expiry issues + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Create flush authorization + IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ + buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + }); + + // Sign with buyer's private key using helper + bytes memory signature = signFlushAuthorization(auth, buyerPrivateKey); + + // Execute flush - should withdraw + uint256 balanceBefore = usdc.balanceOf(buyerFromPrivateKey); + + // Expect both Withdrawn and FlushAuthorized events + vm.expectEmit(true, true, true, true); + emit Withdrawn(buyerFromPrivateKey, seller, address(usdc), depositAmount, 0); + vm.expectEmit(true, true, true, false); + emit FlushAuthorized(buyerFromPrivateKey, seller, address(usdc), nonce, false); // false = no thawing + + escrow.flushWithAuthorization(auth, signature); + + // Verify funds were withdrawn + assertEq(usdc.balanceOf(buyerFromPrivateKey), balanceBefore + depositAmount); + IDeferredPaymentEscrow.EscrowAccount memory account = + escrow.getAccount(buyerFromPrivateKey, seller, address(usdc)); + assertEq(account.balance, 0); + assertEq(account.thawingAmount, 0); + } + + function test_FlushWithAuthorization_NonceReplayReverts() public { + uint256 depositAmount = 1000e6; + bytes32 nonce = keccak256("flush-nonce-replay"); + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Setup: deposit funds + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + // Create flush authorization + IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ + buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + }); + + // Sign authorization + bytes memory signature = signFlushAuthorization(auth, buyerPrivateKey); + + // Execute first flush + escrow.flushWithAuthorization(auth, signature); + + // Try to replay the same authorization + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.NonceAlreadyUsed.selector, nonce)); + escrow.flushWithAuthorization(auth, signature); + } + + function test_FlushWithAuthorization_ThawNotReady() public { + uint256 depositAmount = 1000e6; + bytes32 nonce = keccak256("flush-nonce-2"); + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Setup: deposit funds (not thawed) + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + // Create flush authorization + IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ + buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + }); + + // Sign with buyer's private key + bytes memory signature = signFlushAuthorization(auth, buyerPrivateKey); + + // Execute flush - should initiate thaw + vm.expectEmit(true, true, true, false); + emit FlushAuthorized(buyerFromPrivateKey, seller, address(usdc), nonce, true); // true = thawing initiated + + escrow.flushWithAuthorization(auth, signature); + + // Verify thaw was initiated + IDeferredPaymentEscrow.EscrowAccount memory account = + escrow.getAccount(buyerFromPrivateKey, seller, address(usdc)); + assertEq(account.balance, depositAmount); + assertEq(account.thawingAmount, depositAmount); + assert(account.thawEndTime > block.timestamp); + } + + function test_FlushAllWithAuthorization_EmptyAccountSet() public { + bytes32 nonce = keccak256("flush-all-empty"); + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Create flush all authorization without any accounts + IDeferredPaymentEscrow.FlushAllAuthorization memory auth = + IDeferredPaymentEscrow.FlushAllAuthorization({buyer: buyerFromPrivateKey, nonce: nonce, expiry: expiry}); + + // Sign authorization + bytes memory signature = signFlushAllAuthorization(auth, buyerPrivateKey); + + // Execute flush all - should work but do nothing + vm.expectEmit(true, false, false, true); + emit FlushAllAuthorized(buyerFromPrivateKey, nonce, 0); // 0 accounts flushed + + escrow.flushAllWithAuthorization(auth, signature); + } + + function test_FlushAllWithAuthorization_NonceReplayReverts() public { + uint256 depositAmount = 1000e6; + bytes32 nonce = keccak256("flush-all-replay"); + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Setup: deposit funds + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + // Create flush all authorization + IDeferredPaymentEscrow.FlushAllAuthorization memory auth = + IDeferredPaymentEscrow.FlushAllAuthorization({buyer: buyerFromPrivateKey, nonce: nonce, expiry: expiry}); + + // Sign authorization + bytes memory signature = signFlushAllAuthorization(auth, buyerPrivateKey); + + // Execute first flush all + escrow.flushAllWithAuthorization(auth, signature); + + // Try to replay the same authorization + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.NonceAlreadyUsed.selector, nonce)); + escrow.flushAllWithAuthorization(auth, signature); + } + + function test_FlushWithAuthorization_Idempotent() public { + uint256 depositAmount = 1000e6; + bytes32 nonce = keccak256("flush-idempotent"); + + // Setup: deposit and thaw funds + vm.startPrank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + escrow.thaw(seller, address(usdc), depositAmount); + vm.stopPrank(); + + // Warp to after thawing period + vm.warp(block.timestamp + THAWING_PERIOD + 1); + + // Set expiry AFTER warping to avoid expiry issues + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Create flush authorization with updated expiry + IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ + buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + }); + + bytes memory signature = signFlushAuthorization(auth, buyerPrivateKey); + + // First flush - should withdraw + escrow.flushWithAuthorization(auth, signature); + + // Second flush with same nonce should fail (nonce replay protection) + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.NonceAlreadyUsed.selector, nonce)); + escrow.flushWithAuthorization(auth, signature); + } + + function test_FlushAllWithAuthorization_MultipleAccounts() public { + bytes32 nonce = keccak256("flush-all-nonce-1"); + + // Setup multiple escrow accounts + address seller2 = makeAddr("seller2"); + vm.startPrank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), 1000e6); + escrow.deposit(seller2, address(usdc), 500e6); + escrow.deposit(seller, address(usdt), 800e6); // Different asset + + // Thaw some funds + escrow.thaw(seller, address(usdc), 1000e6); + vm.stopPrank(); + + // Warp to after thawing + vm.warp(block.timestamp + THAWING_PERIOD + 1); + + // Set expiry AFTER warping to avoid expiry issues + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Create flush all authorization + IDeferredPaymentEscrow.FlushAllAuthorization memory auth = + IDeferredPaymentEscrow.FlushAllAuthorization({buyer: buyerFromPrivateKey, nonce: nonce, expiry: expiry}); + + // Sign with buyer's private key + bytes memory signature = signFlushAllAuthorization(auth, buyerPrivateKey); + + // Execute flush all + uint256 usdcBalanceBefore = usdc.balanceOf(buyerFromPrivateKey); + vm.expectEmit(true, false, false, true); + emit FlushAllAuthorized(buyerFromPrivateKey, nonce, 3); // 3 accounts affected + + escrow.flushAllWithAuthorization(auth, signature); + + // Verify results + assertEq(usdc.balanceOf(buyerFromPrivateKey), usdcBalanceBefore + 1000e6); // Withdrawn from ready account + + // Check that other accounts had thawing initiated + IDeferredPaymentEscrow.EscrowAccount memory account2 = + escrow.getAccount(buyerFromPrivateKey, seller2, address(usdc)); + assertEq(account2.thawingAmount, 500e6); // Should have thaw initiated + + IDeferredPaymentEscrow.EscrowAccount memory account3 = + escrow.getAccount(buyerFromPrivateKey, seller, address(usdt)); + assertEq(account3.thawingAmount, 800e6); // Should have thaw initiated + } + + function test_FlushWithAuthorization_WithdrawAndThaw() public { + uint256 depositAmount = 1000e6; + uint256 thawAmount = 400e6; + bytes32 nonce = keccak256("flush-nonce-3"); + + // Setup: deposit, partially thaw + vm.startPrank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + escrow.thaw(seller, address(usdc), thawAmount); + vm.stopPrank(); + + // Warp to after thawing period + vm.warp(block.timestamp + THAWING_PERIOD + 1); + + // Set expiry AFTER warping to avoid expiry issues + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Create flush authorization + IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ + buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + }); + + // Sign with buyer's private key + bytes memory signature = signFlushAuthorization(auth, buyerPrivateKey); + + // Execute flush - should withdraw ready funds AND thaw remaining + uint256 balanceBefore = usdc.balanceOf(buyerFromPrivateKey); + vm.expectEmit(true, true, true, false); + emit FlushAuthorized(buyerFromPrivateKey, seller, address(usdc), nonce, true); // true = also thawed remaining + + escrow.flushWithAuthorization(auth, signature); + + // Verify: withdrew 400, thawed remaining 600 + assertEq(usdc.balanceOf(buyerFromPrivateKey), balanceBefore + thawAmount); + IDeferredPaymentEscrow.EscrowAccount memory account = + escrow.getAccount(buyerFromPrivateKey, seller, address(usdc)); + assertEq(account.balance, depositAmount - thawAmount); + assertEq(account.thawingAmount, depositAmount - thawAmount); + } + + function test_FlushWithAuthorization_ResetsThawTimer() public { + uint256 depositAmount = 1000e6; + uint256 thawAmount = 600e6; + bytes32 nonce = keccak256("flush-reset-timer"); + + // Setup: deposit and thaw funds + vm.startPrank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + escrow.thaw(seller, address(usdc), thawAmount); + vm.stopPrank(); + + uint256 originalThawEndTime = escrow.getAccount(buyerFromPrivateKey, seller, address(usdc)).thawEndTime; + + // Wait some time but not full thawing period + vm.warp(block.timestamp + THAWING_PERIOD / 2); + + // Set expiry + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Create flush authorization + IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ + buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + }); + + // Sign authorization + bytes memory signature = signFlushAuthorization(auth, buyerPrivateKey); + + // Execute flush - should thaw remaining balance and reset timer + escrow.flushWithAuthorization(auth, signature); + + // Verify timer was reset + IDeferredPaymentEscrow.EscrowAccount memory account = + escrow.getAccount(buyerFromPrivateKey, seller, address(usdc)); + uint256 newThawEndTime = account.thawEndTime; + + // New timer should be later than original (reset to full period from current time) + assert(newThawEndTime > originalThawEndTime); + assertEq(account.thawingAmount, depositAmount); // All funds now thawing + } + + function test_FlushAllWithAuthorization_MultipleAssets_ComplexScenario() public { + bytes32 nonce = keccak256("flush-all-complex"); + + // Setup complex scenario with multiple sellers and assets + address seller2 = makeAddr("seller2"); + uint256 usdcAmount1 = 1000e6; + uint256 usdcAmount2 = 500e6; + uint256 usdtAmount = 800e6; + + vm.startPrank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), usdcAmount1); + escrow.deposit(seller2, address(usdc), usdcAmount2); + escrow.deposit(seller, address(usdt), usdtAmount); + + // Thaw funds from first account only + escrow.thaw(seller, address(usdc), usdcAmount1); + vm.stopPrank(); + + // Warp to after thawing period + vm.warp(block.timestamp + THAWING_PERIOD + 1); + uint64 expiry = uint64(block.timestamp + 1 hours); + + // Create flush all authorization + IDeferredPaymentEscrow.FlushAllAuthorization memory auth = + IDeferredPaymentEscrow.FlushAllAuthorization({buyer: buyerFromPrivateKey, nonce: nonce, expiry: expiry}); + + bytes memory signature = signFlushAllAuthorization(auth, buyerPrivateKey); + + // Execute flush all + uint256 usdcBalanceBefore = usdc.balanceOf(buyerFromPrivateKey); + uint256 usdtBalanceBefore = usdt.balanceOf(buyerFromPrivateKey); + + vm.expectEmit(true, false, false, true); + emit FlushAllAuthorized(buyerFromPrivateKey, nonce, 3); // 3 accounts affected + + escrow.flushAllWithAuthorization(auth, signature); + + // Verify withdrawn from ready account + assertEq(usdc.balanceOf(buyerFromPrivateKey), usdcBalanceBefore + usdcAmount1); + assertEq(usdt.balanceOf(buyerFromPrivateKey), usdtBalanceBefore); // No withdrawal from USDT + + // Verify thawing initiated for other accounts + IDeferredPaymentEscrow.EscrowAccount memory account2 = + escrow.getAccount(buyerFromPrivateKey, seller2, address(usdc)); + assertEq(account2.thawingAmount, usdcAmount2); + + IDeferredPaymentEscrow.EscrowAccount memory account3 = + escrow.getAccount(buyerFromPrivateKey, seller, address(usdt)); + assertEq(account3.thawingAmount, usdtAmount); + } +} diff --git a/solidity/packages/deferred-escrow/test/TokenCompatibilityTest.t.sol b/solidity/packages/deferred-escrow/test/TokenCompatibilityTest.t.sol new file mode 100644 index 0000000000..41f18c8259 --- /dev/null +++ b/solidity/packages/deferred-escrow/test/TokenCompatibilityTest.t.sol @@ -0,0 +1,203 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {BaseTest} from "./BaseTest.sol"; +import {IDeferredPaymentEscrow} from "../src/IDeferredPaymentEscrow.sol"; +import {MockERC20} from "./mocks/MockERC20.sol"; +import {MockNonStandardERC20} from "./mocks/MockNonStandardERC20.sol"; + +contract TokenCompatibilityTest is BaseTest { + // ============ TOKEN COMPATIBILITY TESTS ============ + + function test_DifferentTokenDecimals() public { + // Create tokens with different decimals + MockERC20 token6 = new MockERC20("USDC", "USDC", 6); // 6 decimals like real USDC + MockERC20 token18 = new MockERC20("DAI", "DAI", 18); // 18 decimals like DAI + MockERC20 token8 = new MockERC20("WBTC", "WBTC", 8); // 8 decimals like WBTC + + // Mint tokens with appropriate amounts for each decimal + uint256 amount6 = 1000e6; // 1000 USDC + uint256 amount18 = 500e18; // 500 DAI + uint256 amount8 = 1e8; // 1 WBTC + + token6.mint(buyer, amount6); + token18.mint(buyer, amount18); + token8.mint(buyer, amount8); + + // Approve escrow + vm.startPrank(buyer); + token6.approve(address(escrow), amount6); + token18.approve(address(escrow), amount18); + token8.approve(address(escrow), amount8); + + // Deposit all tokens to same seller + escrow.deposit(seller, address(token6), amount6); + escrow.deposit(seller, address(token18), amount18); + escrow.deposit(seller, address(token8), amount8); + vm.stopPrank(); + + // Verify all deposits + assertEq(escrow.getAccount(buyer, seller, address(token6)).balance, amount6); + assertEq(escrow.getAccount(buyer, seller, address(token18)).balance, amount18); + assertEq(escrow.getAccount(buyer, seller, address(token8)).balance, amount8); + + // Create vouchers for each token + bytes32 voucher6Id = keccak256("voucher-usdc"); + bytes32 voucher18Id = keccak256("voucher-dai"); + bytes32 voucher8Id = keccak256("voucher-wbtc"); + + IDeferredPaymentEscrow.Voucher memory voucher6 = + createVoucher(voucher6Id, buyer, seller, amount6, address(token6), voucherTimestamp, 1, voucherExpiry); + IDeferredPaymentEscrow.Voucher memory voucher18 = + createVoucher(voucher18Id, buyer, seller, amount18, address(token18), voucherTimestamp, 1, voucherExpiry); + IDeferredPaymentEscrow.Voucher memory voucher8 = + createVoucher(voucher8Id, buyer, seller, amount8, address(token8), voucherTimestamp, 1, voucherExpiry); + + // We'll use buyer's address directly (not buyerFromPrivateKey) for this test + // So we need to get the buyer's private key from the test framework + uint256 buyerPk = uint256(keccak256(abi.encodePacked("buyer"))); + + bytes memory signature6 = signVoucher(voucher6, buyerPk); + bytes memory signature18 = signVoucher(voucher18, buyerPk); + bytes memory signature8 = signVoucher(voucher8, buyerPk); + + uint256 sellerBalance6Before = token6.balanceOf(seller); + uint256 sellerBalance18Before = token18.balanceOf(seller); + uint256 sellerBalance8Before = token8.balanceOf(seller); + + // Collect all vouchers + vm.startPrank(seller); + escrow.collect(voucher6, signature6); + escrow.collect(voucher18, signature18); + escrow.collect(voucher8, signature8); + vm.stopPrank(); + + // Verify collections + assertEq(token6.balanceOf(seller), sellerBalance6Before + amount6); + assertEq(token18.balanceOf(seller), sellerBalance18Before + amount18); + assertEq(token8.balanceOf(seller), sellerBalance8Before + amount8); + } + + function test_NonStandardERC20Token() public { + MockNonStandardERC20 nonStandardToken = new MockNonStandardERC20("Non-Standard", "NST", 18); + uint256 depositAmount = 1000e18; + + // Mint tokens to buyer + nonStandardToken.mint(buyer, depositAmount); + + // Approve and deposit + vm.startPrank(buyer); + nonStandardToken.approve(address(escrow), depositAmount); + escrow.deposit(seller, address(nonStandardToken), depositAmount); + vm.stopPrank(); + + // Verify deposit + assertEq(escrow.getAccount(buyer, seller, address(nonStandardToken)).balance, depositAmount); + + // Create and collect voucher + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyer, seller, VOUCHER_VALUE, address(nonStandardToken), voucherTimestamp, 1, voucherExpiry + ); + + uint256 buyerPk = uint256(keccak256(abi.encodePacked("buyer"))); + bytes memory signature = signVoucher(voucher, buyerPk); + + vm.prank(seller); + escrow.collect(voucher, signature); + + // Verify collection worked with non-standard token + assertEq(nonStandardToken.balanceOf(seller), VOUCHER_VALUE); + } + + function test_Collect_ERC1271() public { + uint256 depositAmount = 1000e18; + + // Mint tokens to smart wallet + usdc.mint(address(smartWallet), depositAmount); + + // Smart wallet approves escrow + vm.prank(address(smartWallet)); + usdc.approve(address(escrow), depositAmount); + + // Smart wallet deposits + vm.prank(address(smartWallet)); + escrow.deposit(seller, address(usdc), depositAmount); + + // Create voucher for smart wallet + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, address(smartWallet), seller, VOUCHER_VALUE, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + // Create digest for smart wallet validation + bytes32 structHash = keccak256( + abi.encode( + escrow.VOUCHER_TYPEHASH(), + voucher.id, + voucher.buyer, + voucher.seller, + voucher.valueAggregate, + voucher.asset, + voucher.timestamp, + voucher.nonce, + voucher.escrow, + voucher.chainId, + voucher.expiry + ) + ); + bytes32 digest = keccak256(abi.encodePacked("\x19\x01", escrow.DOMAIN_SEPARATOR(), structHash)); + + // Set smart wallet to accept this digest + smartWallet.setValidHash(digest, true); + bytes memory signature = abi.encodePacked("valid"); + + vm.prank(seller); + escrow.collect(voucher, signature); + + assertEq(escrow.getVoucherCollected(address(smartWallet), seller, address(usdc), VOUCHER_ID), VOUCHER_VALUE); + } + + function test_DepositMany_DifferentTokenDecimals() public { + // Create tokens with different decimals + MockERC20 token6 = new MockERC20("USDC", "USDC", 6); + MockERC20 token18 = new MockERC20("DAI", "DAI", 18); + + // Test amounts appropriate for each decimal + uint256 amount6 = 1000e6; // 1000 USDC + uint256 amount18 = 500e18; // 500 DAI + + // Test with 6-decimal token + token6.mint(buyer, amount6 * 3); + vm.startPrank(buyer); + token6.approve(address(escrow), amount6 * 3); + + address seller2 = makeAddr("seller2"); + address seller3 = makeAddr("seller3"); + + IDeferredPaymentEscrow.DepositInput[] memory deposits6 = new IDeferredPaymentEscrow.DepositInput[](3); + deposits6[0] = IDeferredPaymentEscrow.DepositInput({seller: seller, amount: amount6}); + deposits6[1] = IDeferredPaymentEscrow.DepositInput({seller: seller2, amount: amount6}); + deposits6[2] = IDeferredPaymentEscrow.DepositInput({seller: seller3, amount: amount6}); + + escrow.depositMany(address(token6), deposits6); + vm.stopPrank(); + + // Test with 18-decimal token + token18.mint(buyer, amount18 * 2); + vm.startPrank(buyer); + token18.approve(address(escrow), amount18 * 2); + + IDeferredPaymentEscrow.DepositInput[] memory deposits18 = new IDeferredPaymentEscrow.DepositInput[](2); + deposits18[0] = IDeferredPaymentEscrow.DepositInput({seller: seller, amount: amount18}); + deposits18[1] = IDeferredPaymentEscrow.DepositInput({seller: seller2, amount: amount18}); + + escrow.depositMany(address(token18), deposits18); + vm.stopPrank(); + + // Verify all deposits + assertEq(escrow.getAccount(buyer, seller, address(token6)).balance, amount6); + assertEq(escrow.getAccount(buyer, seller2, address(token6)).balance, amount6); + assertEq(escrow.getAccount(buyer, seller3, address(token6)).balance, amount6); + assertEq(escrow.getAccount(buyer, seller, address(token18)).balance, amount18); + assertEq(escrow.getAccount(buyer, seller2, address(token18)).balance, amount18); + } +} diff --git a/solidity/packages/deferred-escrow/test/ViewFunctionTest.t.sol b/solidity/packages/deferred-escrow/test/ViewFunctionTest.t.sol new file mode 100644 index 0000000000..2a0f2cfa79 --- /dev/null +++ b/solidity/packages/deferred-escrow/test/ViewFunctionTest.t.sol @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {BaseTest} from "./BaseTest.sol"; +import {IDeferredPaymentEscrow} from "../src/IDeferredPaymentEscrow.sol"; + +contract ViewFunctionTest is BaseTest { + // ============ VIEW FUNCTION TESTS ============ + + function test_GetOutstandingAndCollectableAmount() public { + uint256 depositAmount = 1000e18; + uint256 voucherAmount = 2000e18; + + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, voucherAmount, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + (uint256 outstanding, uint256 collectable) = escrow.getOutstandingAndCollectableAmount(voucher); + assertEq(outstanding, voucherAmount); // Full voucher amount is outstanding + assertEq(collectable, depositAmount); // Limited by balance + } + + function test_GetOutstandingAndCollectableAmount_PartialBalance() public { + uint256 depositAmount = 500e18; + uint256 voucherAmount = 1000e18; + + // Deposit partial amount + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, voucherAmount, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + (uint256 outstanding, uint256 collectable) = escrow.getOutstandingAndCollectableAmount(voucher); + assertEq(outstanding, voucherAmount); + assertEq(collectable, depositAmount); // Limited by available balance + } + + function test_GetOutstandingAndCollectableAmount_FullyCollected() public { + uint256 depositAmount = 1000e18; + + // Deposit and collect + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, VOUCHER_VALUE, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + vm.prank(seller); + escrow.collect(voucher, signature); + + // Check after collection + (uint256 outstanding, uint256 collectable) = escrow.getOutstandingAndCollectableAmount(voucher); + assertEq(outstanding, 0); + assertEq(collectable, 0); + } + + function test_IsSignatureValid() public { + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, VOUCHER_VALUE, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + assertTrue(escrow.isVoucherSignatureValid(voucher, signature)); + + bytes memory invalidSignature = abi.encodePacked(uint256(123), uint256(456), uint8(27)); + assertFalse(escrow.isVoucherSignatureValid(voucher, invalidSignature)); + } + + function test_AlternativeViewFunctions() public { + // Test all the signature validation functions + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, VOUCHER_VALUE, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory voucherSignature = signVoucher(voucher, buyerPrivateKey); + assertTrue(escrow.isVoucherSignatureValid(voucher, voucherSignature)); + + // Test deposit authorization validation + IDeferredPaymentEscrow.DepositAuthorization memory depositAuth = IDeferredPaymentEscrow.DepositAuthorization({ + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + amount: 1000e6, + nonce: keccak256("deposit-nonce"), + expiry: voucherExpiry + }); + + bytes memory depositSignature = signDepositAuthorization(depositAuth, buyerPrivateKey); + assertTrue(escrow.isDepositAuthorizationValid(depositAuth, depositSignature)); + + // Test flush authorization validation + IDeferredPaymentEscrow.FlushAuthorization memory flushAuth = IDeferredPaymentEscrow.FlushAuthorization({ + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + nonce: keccak256("flush-nonce"), + expiry: voucherExpiry + }); + + bytes memory flushSignature = signFlushAuthorization(flushAuth, buyerPrivateKey); + assertTrue(escrow.isFlushAuthorizationValid(flushAuth, flushSignature)); + + // Test flush all authorization validation + IDeferredPaymentEscrow.FlushAllAuthorization memory flushAllAuth = IDeferredPaymentEscrow.FlushAllAuthorization({ + buyer: buyerFromPrivateKey, nonce: keccak256("flush-all-nonce"), expiry: voucherExpiry + }); + + bytes memory flushAllSignature = signFlushAllAuthorization(flushAllAuth, buyerPrivateKey); + assertTrue(escrow.isFlushAllAuthorizationValid(flushAllAuth, flushAllSignature)); + } +} diff --git a/solidity/packages/deferred-escrow/test/VoucherCollectionTest.t.sol b/solidity/packages/deferred-escrow/test/VoucherCollectionTest.t.sol new file mode 100644 index 0000000000..69c319c68d --- /dev/null +++ b/solidity/packages/deferred-escrow/test/VoucherCollectionTest.t.sol @@ -0,0 +1,365 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {BaseTest} from "./BaseTest.sol"; +import {IDeferredPaymentEscrow} from "../src/IDeferredPaymentEscrow.sol"; + +contract VoucherCollectionTest is BaseTest { + // ============ VOUCHER COLLECTION TESTS ============ + + function test_Collect() public { + uint256 depositAmount = 2000e18; + uint256 collectAmount = 1000e18; + + // Deposit funds + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + // Create and sign voucher + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, collectAmount, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + vm.expectEmit(true, true, true, true); + emit VoucherCollected(VOUCHER_ID, buyerFromPrivateKey, seller, address(usdc), collectAmount, collectAmount); + + uint256 sellerBalanceBefore = usdc.balanceOf(seller); + + vm.prank(seller); + escrow.collect(voucher, signature); + + assertEq(usdc.balanceOf(seller), sellerBalanceBefore + collectAmount); // Seller gets full amount + assertEq(escrow.getVoucherCollected(buyerFromPrivateKey, seller, address(usdc), VOUCHER_ID), collectAmount); + } + + function test_Collect_AdjustsThawingAmount() public { + uint256 depositAmount = 1000e18; + uint256 thawAmount = 800e18; + uint256 voucherAmount = 600e18; + + // Deposit funds + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + // Start thawing most of the funds + vm.prank(buyerFromPrivateKey); + escrow.thaw(seller, address(usdc), thawAmount); + + // Create voucher that will bring balance below thawing amount + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, voucherAmount, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + // Collect + vm.prank(seller); + escrow.collect(voucher, signature); + + // Check that thawing amount was adjusted down + IDeferredPaymentEscrow.EscrowAccount memory accountAfter = + escrow.getAccount(buyerFromPrivateKey, seller, address(usdc)); + assertEq(accountAfter.balance, 400e18); // 1000e18 - 600e18 + assertEq(accountAfter.thawingAmount, 400e18); // Adjusted down to match balance + } + + function test_Collect_FullBalanceAvailableDuringThaw() public { + uint256 depositAmount = 1000e18; + uint256 thawAmount = 800e18; + uint256 voucherAmount = 900e18; // More than thawing amount + + // Deposit funds + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + // Start thawing most of the funds + vm.prank(buyerFromPrivateKey); + escrow.thaw(seller, address(usdc), thawAmount); + + // Verify initial state - balance unchanged, thawing active + IDeferredPaymentEscrow.EscrowAccount memory accountBefore = + escrow.getAccount(buyerFromPrivateKey, seller, address(usdc)); + assertEq(accountBefore.balance, 1000e18); + assertEq(accountBefore.thawingAmount, 800e18); + + // Create voucher for amount greater than thawing (but less than balance) + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, voucherAmount, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + // Collect should succeed - full balance is available + vm.prank(seller); + escrow.collect(voucher, signature); + + // Verify collection succeeded and thawing was adjusted + IDeferredPaymentEscrow.EscrowAccount memory accountAfter = + escrow.getAccount(buyerFromPrivateKey, seller, address(usdc)); + assertEq(accountAfter.balance, 100e18); // 1000e18 - 900e18 + assertEq(accountAfter.thawingAmount, 100e18); // Adjusted to match remaining balance + assertEq(escrow.getVoucherCollected(buyerFromPrivateKey, seller, address(usdc), VOUCHER_ID), voucherAmount); + } + + function test_Collect_PartialCollection() public { + uint256 depositAmount = 500e18; + uint256 voucherAmount = 1000e18; + + // Deposit less than voucher amount + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, voucherAmount, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + // Should only collect the available balance + vm.expectEmit(true, true, true, true); + emit VoucherCollected(VOUCHER_ID, buyerFromPrivateKey, seller, address(usdc), depositAmount, depositAmount); + + vm.prank(seller); + escrow.collect(voucher, signature); + + assertEq(escrow.getVoucherCollected(buyerFromPrivateKey, seller, address(usdc), VOUCHER_ID), depositAmount); + assertEq(escrow.getAccount(buyerFromPrivateKey, seller, address(usdc)).balance, 0); + } + + function test_Collect_PermissionlessCollection() public { + uint256 depositAmount = 1000e18; + + // Deposit funds + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, VOUCHER_VALUE, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + // Anyone can collect on behalf of the seller + address randomUser = makeAddr("randomUser"); + vm.prank(randomUser); + escrow.collect(voucher, signature); + + // Seller still gets the funds + assertEq(usdc.balanceOf(seller), VOUCHER_VALUE); + assertEq(escrow.getVoucherCollected(buyerFromPrivateKey, seller, address(usdc), VOUCHER_ID), VOUCHER_VALUE); + } + + function test_Collect_IdempotentBehavior() public { + uint256 depositAmount = 1000e18; + + // Deposit funds + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, VOUCHER_VALUE, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + // First collection + vm.prank(seller); + escrow.collect(voucher, signature); + + uint256 sellerBalanceAfterFirst = usdc.balanceOf(seller); + + // Second collection - should emit VoucherAlreadyCollected and do nothing + vm.expectEmit(true, true, true, true); + emit VoucherAlreadyCollected(VOUCHER_ID, buyerFromPrivateKey, seller, address(usdc), VOUCHER_VALUE); + + vm.prank(seller); + escrow.collect(voucher, signature); + + // No additional transfer + assertEq(usdc.balanceOf(seller), sellerBalanceAfterFirst); + } + + function test_CollectMany_IdempotentBehavior() public { + uint256 depositAmount = 2000e18; + + // Deposit funds + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + // Create multiple vouchers + bytes32 voucher1Id = keccak256("voucher-1"); + bytes32 voucher2Id = keccak256("voucher-2"); + + IDeferredPaymentEscrow.Voucher memory voucher1 = createVoucher( + voucher1Id, buyerFromPrivateKey, seller, 800e18, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + IDeferredPaymentEscrow.Voucher memory voucher2 = createVoucher( + voucher2Id, buyerFromPrivateKey, seller, 700e18, address(usdc), voucherTimestamp, 2, voucherExpiry + ); + + IDeferredPaymentEscrow.SignedVoucher[] memory signedVouchers = new IDeferredPaymentEscrow.SignedVoucher[](2); + signedVouchers[0] = IDeferredPaymentEscrow.SignedVoucher({ + voucher: voucher1, signature: signVoucher(voucher1, buyerPrivateKey) + }); + signedVouchers[1] = IDeferredPaymentEscrow.SignedVoucher({ + voucher: voucher2, signature: signVoucher(voucher2, buyerPrivateKey) + }); + + // First batch collection + vm.prank(seller); + escrow.collectMany(signedVouchers); + + uint256 sellerBalanceAfterFirst = usdc.balanceOf(seller); + + // Second batch collection - should be idempotent + vm.prank(seller); + escrow.collectMany(signedVouchers); + + // No additional transfer + assertEq(usdc.balanceOf(seller), sellerBalanceAfterFirst); + } + + // ============ COLLECTION VALIDATION TESTS ============ + + function test_Collect_ExpiredVoucher() public { + // Deposit funds + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), 1000e18); + + // Create expired voucher + IDeferredPaymentEscrow.Voucher memory expiredVoucher = createVoucher( + VOUCHER_ID, + buyerFromPrivateKey, + seller, + VOUCHER_VALUE, + address(usdc), + voucherTimestamp, + 1, + uint64(block.timestamp - 1) // Already expired + ); + + bytes memory signature = signVoucher(expiredVoucher, buyerPrivateKey); + + vm.prank(seller); + vm.expectRevert( + abi.encodeWithSelector( + IDeferredPaymentEscrow.VoucherExpired.selector, VOUCHER_ID, block.timestamp, expiredVoucher.expiry + ) + ); + escrow.collect(expiredVoucher, signature); + } + + function test_Collect_InvalidSignature() public { + // Deposit funds + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), 1000e18); + + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, VOUCHER_VALUE, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + // Wrong signature + bytes memory wrongSignature = hex"1234567890abcdef"; + + vm.prank(seller); + vm.expectRevert( + abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidSignature.selector, VOUCHER_ID, buyerFromPrivateKey) + ); + escrow.collect(voucher, wrongSignature); + } + + function test_CollectMany_EmptyVouchers() public { + IDeferredPaymentEscrow.SignedVoucher[] memory emptyVouchers = new IDeferredPaymentEscrow.SignedVoucher[](0); + + vm.prank(seller); + vm.expectRevert(IDeferredPaymentEscrow.NoVouchersProvided.selector); + escrow.collectMany(emptyVouchers); + } + + function test_Collect_InvalidVoucherBuyer() public { + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, address(0), seller, VOUCHER_VALUE, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAddress.selector, address(0))); + escrow.collect(voucher, signature); + } + + function test_Collect_InvalidVoucherAsset() public { + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, VOUCHER_VALUE, address(0), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAsset.selector, address(0))); + escrow.collect(voucher, signature); + } + + function test_Collect_ZeroVoucherValue() public { + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, 0, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + vm.expectRevert(abi.encodeWithSelector(IDeferredPaymentEscrow.InvalidAmount.selector, 0)); + escrow.collect(voucher, signature); + } + + function test_Collect_ZeroFundsAvailable() public { + // Don't deposit any funds, just try to collect + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, VOUCHER_VALUE, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + vm.expectEmit(true, true, true, true); + emit VoucherNoCollectableBalance(VOUCHER_ID, buyerFromPrivateKey, seller, address(usdc), VOUCHER_VALUE, 0); + + vm.prank(seller); + escrow.collect(voucher, signature); + + // No funds should be transferred + assertEq(usdc.balanceOf(seller), 0); + assertEq(escrow.getVoucherCollected(buyerFromPrivateKey, seller, address(usdc), VOUCHER_ID), 0); + } + + function test_Collect_PartialThenZeroBalance() public { + uint256 depositAmount = 500e18; + uint256 voucherAmount = 1000e18; + + // Deposit partial amount + vm.prank(buyerFromPrivateKey); + escrow.deposit(seller, address(usdc), depositAmount); + + IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( + VOUCHER_ID, buyerFromPrivateKey, seller, voucherAmount, address(usdc), voucherTimestamp, 1, voucherExpiry + ); + + bytes memory signature = signVoucher(voucher, buyerPrivateKey); + + // First collection - partial + vm.expectEmit(true, true, true, true); + emit VoucherCollected(VOUCHER_ID, buyerFromPrivateKey, seller, address(usdc), depositAmount, depositAmount); + + vm.prank(seller); + escrow.collect(voucher, signature); + + // Second collection attempt - should emit NoCollectableBalance + vm.expectEmit(true, true, true, true); + emit VoucherNoCollectableBalance(VOUCHER_ID, buyerFromPrivateKey, seller, address(usdc), 500e18, depositAmount); + + vm.prank(seller); + escrow.collect(voucher, signature); + + // Verify state + assertEq(escrow.getVoucherCollected(buyerFromPrivateKey, seller, address(usdc), VOUCHER_ID), depositAmount); + assertEq(escrow.getAccount(buyerFromPrivateKey, seller, address(usdc)).balance, 0); + } +} diff --git a/solidity/packages/deferred-escrow/test/mocks/MockERC1271.sol b/solidity/packages/deferred-escrow/test/mocks/MockERC1271.sol new file mode 100644 index 0000000000..fdce651eab --- /dev/null +++ b/solidity/packages/deferred-escrow/test/mocks/MockERC1271.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol"; + +/** + * @title MockERC1271 + * @notice Mock smart contract wallet for testing ERC-1271 signature validation + */ +contract MockERC1271 is IERC1271 { + bytes4 internal constant MAGICVALUE = 0x1626ba7e; + bytes4 internal constant INVALID_SIGNATURE = 0xffffffff; + + mapping(bytes32 => bool) public validHashes; + + function setValidHash(bytes32 hash, bool isValid) external { + validHashes[hash] = isValid; + } + + function isValidSignature(bytes32 hash, bytes memory) external view override returns (bytes4 magicValue) { + return validHashes[hash] ? MAGICVALUE : INVALID_SIGNATURE; + } +} diff --git a/solidity/packages/deferred-escrow/test/mocks/MockERC20.sol b/solidity/packages/deferred-escrow/test/mocks/MockERC20.sol new file mode 100644 index 0000000000..ed9d522452 --- /dev/null +++ b/solidity/packages/deferred-escrow/test/mocks/MockERC20.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +/** + * @title MockERC20 + * @notice Mock ERC20 token for testing purposes + */ +contract MockERC20 is ERC20 { + uint8 private _decimals; + + constructor(string memory name, string memory symbol, uint8 decimals_) ERC20(name, symbol) { + _decimals = decimals_; + } + + function decimals() public view override returns (uint8) { + return _decimals; + } + + function mint(address to, uint256 amount) external { + _mint(to, amount); + } + + function burn(address from, uint256 amount) external { + _burn(from, amount); + } +} diff --git a/solidity/packages/deferred-escrow/test/mocks/MockNonStandardERC20.sol b/solidity/packages/deferred-escrow/test/mocks/MockNonStandardERC20.sol new file mode 100644 index 0000000000..4a18f72ed1 --- /dev/null +++ b/solidity/packages/deferred-escrow/test/mocks/MockNonStandardERC20.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.30; + +/** + * @title MockNonStandardERC20 + * @notice Mock ERC20 token that doesn't return bool from transfer/transferFrom + * @dev Mimics tokens like USDT that don't return bool from transfer functions + */ +contract MockNonStandardERC20 { + string public name; + string public symbol; + uint8 public decimals; + uint256 public totalSupply; + + mapping(address => uint256) public balanceOf; + mapping(address => mapping(address => uint256)) public allowance; + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + + constructor(string memory _name, string memory _symbol, uint8 _decimals) { + name = _name; + symbol = _symbol; + decimals = _decimals; + } + + function mint(address to, uint256 amount) external { + balanceOf[to] += amount; + totalSupply += amount; + emit Transfer(address(0), to, amount); + } + + function burn(address from, uint256 amount) external { + balanceOf[from] -= amount; + totalSupply -= amount; + emit Transfer(from, address(0), amount); + } + + // Non-standard: doesn't return bool + function transfer(address to, uint256 amount) external { + require(balanceOf[msg.sender] >= amount, "Insufficient balance"); + balanceOf[msg.sender] -= amount; + balanceOf[to] += amount; + emit Transfer(msg.sender, to, amount); + } + + // Non-standard: doesn't return bool + function transferFrom(address from, address to, uint256 amount) external { + require(balanceOf[from] >= amount, "Insufficient balance"); + require(allowance[from][msg.sender] >= amount, "Insufficient allowance"); + + balanceOf[from] -= amount; + balanceOf[to] += amount; + allowance[from][msg.sender] -= amount; + + emit Transfer(from, to, amount); + } + + function approve(address spender, uint256 amount) external returns (bool) { + allowance[msg.sender][spender] = amount; + emit Approval(msg.sender, spender, amount); + return true; + } +} From 1553786e88cd4aa9bfa14df62f22bc5c6626f23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 29 Sep 2025 16:25:21 -0300 Subject: [PATCH 076/116] docs: update deferred spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- specs/schemes/deferred/scheme_deferred.md | 7 +++-- .../scheme_deferred_evm_escrow_contract.md | 4 ++- .../scheme_deferred_evm_facilitator.md | 28 ------------------- 3 files changed, 7 insertions(+), 32 deletions(-) diff --git a/specs/schemes/deferred/scheme_deferred.md b/specs/schemes/deferred/scheme_deferred.md index ad3451d54e..77784d0555 100644 --- a/specs/schemes/deferred/scheme_deferred.md +++ b/specs/schemes/deferred/scheme_deferred.md @@ -2,13 +2,14 @@ ## Summary -`deferred` is a scheme designed to support micro-payments between AI agents or automated clients. Unlike the `exact` scheme, which requires a payment to be executed immediately and fully on-chain, `deferred` allows clients to issue signed vouchers (IOUs) off-chain, which can later be aggregated and redeemed by the seller. This scheme enables payments smaller than the minimum feasible on-chain transaction cost. +`deferred` is a scheme designed to support trust minimized micro-payments. Unlike the `exact` scheme, which requires a payment to be executed immediately and fully on-chain, `deferred` allows clients to issue signed vouchers (IOUs) off-chain, which can later be aggregated and redeemed by the seller. This scheme enables payments smaller than the minimum feasible on-chain transaction cost. `deferred` payment scheme requires the seller to store and manage the buyer's vouchers until their eventual on chain settlement. To simplify their setup sellers might choose to offload this task to trusted third parties providing these services, i.e facilitators. ## Example Use Cases -- An LLM paying to use a tool -- Any case where payments are smaller than on-chain settlement costs +- AI agents or automated clients. +- Consuming an API requiring micro cent cost per request. +- Any case where payments are smaller than on-chain settlement costs. ## Appendix \ No newline at end of file diff --git a/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md b/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md index e639f6a219..d82bc58339 100644 --- a/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md +++ b/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md @@ -66,7 +66,7 @@ Buyer → deposit(seller, asset, amount) → Escrow Contract OR -Facilitator → depositWithAuthorization(auth, signature) → Escrow Contract +Buyer → depositWithAuthorization(auth, signature) → Escrow Contract ``` ### 2. Service & Voucher Phase @@ -207,6 +207,8 @@ struct FlushAllAuthorization { - `MAX_THAWING_PERIOD()` → `uint256` - Maximum allowed thawing period (30 days) - `DOMAIN_SEPARATOR()` → `bytes32` - EIP-712 domain separator +## Appendix + ### Multi-Chain Deployment While each contract instance operates on a single chain, the design supports multi-chain deployments: diff --git a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md index 473272bb24..b1d0a26aec 100644 --- a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md +++ b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md @@ -228,31 +228,3 @@ Retrieves settlement history for a voucher. } } ``` - -## Error Responses - -All endpoints return standard HTTP status codes: - -- **200 OK**: Successful operation -- **201 Created**: Resource created successfully -- **400 Bad Request**: Invalid request parameters or voucher data -- **401 Unauthorized**: Authentication required or failed -- **403 Forbidden**: Operation not permitted for authenticated user -- **404 Not Found**: Resource not found -- **500 Internal Server Error**: Facilitator error - -Error responses include a JSON body: -```json -{ - "error": "Human-readable error message", - "code": "ERROR_CODE" -} -``` - -## Implementation Notes - -1. **Voucher Storage**: Facilitators MUST implement persistent storage following the [Voucher Store Specification](./voucher_store.md) -2. **Signature Verification**: All voucher signatures MUST be verified before storage -3. **Seller Authorization**: Write operations SHOULD be restricted to the voucher's designated seller -4. **Rate Limiting**: Facilitators MAY implement rate limiting to prevent abuse -5. **Caching**: GET endpoints MAY implement caching for performance From f5b3654e0b0f2d22068a10616fe588c778d08541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 29 Sep 2025 16:42:48 -0300 Subject: [PATCH 077/116] fix: integrate deferred contract properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .gitignore | 4 ++++ .gitmodules | 9 +++++++++ .../{packages => }/deferred-escrow/README.md | 6 ++---- .../deferred-escrow/addresses.json | 0 .../deferred-escrow/foundry.toml | 0 solidity/deferred-escrow/lib/forge-std | 1 + .../lib/openzeppelin-contracts | 1 + .../lib/safe-singleton-deployer-sol | 1 + .../script/CalculateStorageSlot.s.sol | 0 .../deferred-escrow/script/Deploy.s.sol | 0 .../script/DepositToEscrow.s.sol | 0 .../deferred-escrow/script/README.md | 0 .../deferred-escrow/script/verify.sh | 0 .../src/DeferredPaymentEscrow.sol | 0 .../src/IDeferredPaymentEscrow.sol | 0 .../src/libraries/EscrowSignatureLib.sol | 0 .../deferred-escrow/test/BaseTest.sol | 0 .../deferred-escrow/test/DepositTest.t.sol | 0 .../test/ThawWithdrawTest.t.sol | 0 .../test/TokenCompatibilityTest.t.sol | 0 .../test/ViewFunctionTest.t.sol | 0 .../test/VoucherCollectionTest.t.sol | 0 .../test/mocks/MockERC1271.sol | 0 .../deferred-escrow/test/mocks/MockERC20.sol | 0 .../test/mocks/MockNonStandardERC20.sol | 0 solidity/packages/deferred-escrow/.gitignore | 19 ------------------- .../scheme_deferred_evm_escrow_contract.md | 6 +++++- 27 files changed, 23 insertions(+), 24 deletions(-) create mode 100644 .gitmodules rename solidity/{packages => }/deferred-escrow/README.md (81%) rename solidity/{packages => }/deferred-escrow/addresses.json (100%) rename solidity/{packages => }/deferred-escrow/foundry.toml (100%) create mode 160000 solidity/deferred-escrow/lib/forge-std create mode 160000 solidity/deferred-escrow/lib/openzeppelin-contracts create mode 160000 solidity/deferred-escrow/lib/safe-singleton-deployer-sol rename solidity/{packages => }/deferred-escrow/script/CalculateStorageSlot.s.sol (100%) rename solidity/{packages => }/deferred-escrow/script/Deploy.s.sol (100%) rename solidity/{packages => }/deferred-escrow/script/DepositToEscrow.s.sol (100%) rename solidity/{packages => }/deferred-escrow/script/README.md (100%) rename solidity/{packages => }/deferred-escrow/script/verify.sh (100%) rename solidity/{packages => }/deferred-escrow/src/DeferredPaymentEscrow.sol (100%) rename solidity/{packages => }/deferred-escrow/src/IDeferredPaymentEscrow.sol (100%) rename solidity/{packages => }/deferred-escrow/src/libraries/EscrowSignatureLib.sol (100%) rename solidity/{packages => }/deferred-escrow/test/BaseTest.sol (100%) rename solidity/{packages => }/deferred-escrow/test/DepositTest.t.sol (100%) rename solidity/{packages => }/deferred-escrow/test/ThawWithdrawTest.t.sol (100%) rename solidity/{packages => }/deferred-escrow/test/TokenCompatibilityTest.t.sol (100%) rename solidity/{packages => }/deferred-escrow/test/ViewFunctionTest.t.sol (100%) rename solidity/{packages => }/deferred-escrow/test/VoucherCollectionTest.t.sol (100%) rename solidity/{packages => }/deferred-escrow/test/mocks/MockERC1271.sol (100%) rename solidity/{packages => }/deferred-escrow/test/mocks/MockERC20.sol (100%) rename solidity/{packages => }/deferred-escrow/test/mocks/MockNonStandardERC20.sol (100%) delete mode 100644 solidity/packages/deferred-escrow/.gitignore diff --git a/.gitignore b/.gitignore index 9dc1c8ff9a..7b103451ed 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,7 @@ proxy .env __pycache__/ **/.DS_Store +cache/ +out/ +lcov.info +broadcast/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..dafa1f3222 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "solidity/deferred-escrow/lib/openzeppelin-contracts"] + path = solidity/deferred-escrow/lib/openzeppelin-contracts + url = https://github.com/OpenZeppelin/openzeppelin-contracts +[submodule "solidity/deferred-escrow/lib/forge-std"] + path = solidity/deferred-escrow/lib/forge-std + url = https://github.com/foundry-rs/forge-std +[submodule "solidity/deferred-escrow/lib/safe-singleton-deployer-sol"] + path = solidity/deferred-escrow/lib/safe-singleton-deployer-sol + url = https://github.com/wilsoncusack/safe-singleton-deployer-sol diff --git a/solidity/packages/deferred-escrow/README.md b/solidity/deferred-escrow/README.md similarity index 81% rename from solidity/packages/deferred-escrow/README.md rename to solidity/deferred-escrow/README.md index 073528c13f..3d9d67abf3 100644 --- a/solidity/packages/deferred-escrow/README.md +++ b/solidity/deferred-escrow/README.md @@ -1,8 +1,6 @@ -## A2AP Contracts +## DeferredPaymentEscrow -These contracts will implement the escrowing and vouchers mechanism needed for the `deferred` x402 payment scheme. - -The main contract is DeferredPaymentEscrow.sol. +Smart contracts implementing escrowing and vouchers mechanisms needed for the `deferred` x402 payment scheme. The main contract is `DeferredPaymentEscrow.sol`. ## Usage diff --git a/solidity/packages/deferred-escrow/addresses.json b/solidity/deferred-escrow/addresses.json similarity index 100% rename from solidity/packages/deferred-escrow/addresses.json rename to solidity/deferred-escrow/addresses.json diff --git a/solidity/packages/deferred-escrow/foundry.toml b/solidity/deferred-escrow/foundry.toml similarity index 100% rename from solidity/packages/deferred-escrow/foundry.toml rename to solidity/deferred-escrow/foundry.toml diff --git a/solidity/deferred-escrow/lib/forge-std b/solidity/deferred-escrow/lib/forge-std new file mode 160000 index 0000000000..8bbcf6e3f8 --- /dev/null +++ b/solidity/deferred-escrow/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 8bbcf6e3f8f62f419e5429a0bd89331c85c37824 diff --git a/solidity/deferred-escrow/lib/openzeppelin-contracts b/solidity/deferred-escrow/lib/openzeppelin-contracts new file mode 160000 index 0000000000..c64a1edb67 --- /dev/null +++ b/solidity/deferred-escrow/lib/openzeppelin-contracts @@ -0,0 +1 @@ +Subproject commit c64a1edb67b6e3f4a15cca8909c9482ad33a02b0 diff --git a/solidity/deferred-escrow/lib/safe-singleton-deployer-sol b/solidity/deferred-escrow/lib/safe-singleton-deployer-sol new file mode 160000 index 0000000000..cf2b89c33f --- /dev/null +++ b/solidity/deferred-escrow/lib/safe-singleton-deployer-sol @@ -0,0 +1 @@ +Subproject commit cf2b89c33fed536c4dd6fef2fb84f39053068868 diff --git a/solidity/packages/deferred-escrow/script/CalculateStorageSlot.s.sol b/solidity/deferred-escrow/script/CalculateStorageSlot.s.sol similarity index 100% rename from solidity/packages/deferred-escrow/script/CalculateStorageSlot.s.sol rename to solidity/deferred-escrow/script/CalculateStorageSlot.s.sol diff --git a/solidity/packages/deferred-escrow/script/Deploy.s.sol b/solidity/deferred-escrow/script/Deploy.s.sol similarity index 100% rename from solidity/packages/deferred-escrow/script/Deploy.s.sol rename to solidity/deferred-escrow/script/Deploy.s.sol diff --git a/solidity/packages/deferred-escrow/script/DepositToEscrow.s.sol b/solidity/deferred-escrow/script/DepositToEscrow.s.sol similarity index 100% rename from solidity/packages/deferred-escrow/script/DepositToEscrow.s.sol rename to solidity/deferred-escrow/script/DepositToEscrow.s.sol diff --git a/solidity/packages/deferred-escrow/script/README.md b/solidity/deferred-escrow/script/README.md similarity index 100% rename from solidity/packages/deferred-escrow/script/README.md rename to solidity/deferred-escrow/script/README.md diff --git a/solidity/packages/deferred-escrow/script/verify.sh b/solidity/deferred-escrow/script/verify.sh similarity index 100% rename from solidity/packages/deferred-escrow/script/verify.sh rename to solidity/deferred-escrow/script/verify.sh diff --git a/solidity/packages/deferred-escrow/src/DeferredPaymentEscrow.sol b/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol similarity index 100% rename from solidity/packages/deferred-escrow/src/DeferredPaymentEscrow.sol rename to solidity/deferred-escrow/src/DeferredPaymentEscrow.sol diff --git a/solidity/packages/deferred-escrow/src/IDeferredPaymentEscrow.sol b/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol similarity index 100% rename from solidity/packages/deferred-escrow/src/IDeferredPaymentEscrow.sol rename to solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol diff --git a/solidity/packages/deferred-escrow/src/libraries/EscrowSignatureLib.sol b/solidity/deferred-escrow/src/libraries/EscrowSignatureLib.sol similarity index 100% rename from solidity/packages/deferred-escrow/src/libraries/EscrowSignatureLib.sol rename to solidity/deferred-escrow/src/libraries/EscrowSignatureLib.sol diff --git a/solidity/packages/deferred-escrow/test/BaseTest.sol b/solidity/deferred-escrow/test/BaseTest.sol similarity index 100% rename from solidity/packages/deferred-escrow/test/BaseTest.sol rename to solidity/deferred-escrow/test/BaseTest.sol diff --git a/solidity/packages/deferred-escrow/test/DepositTest.t.sol b/solidity/deferred-escrow/test/DepositTest.t.sol similarity index 100% rename from solidity/packages/deferred-escrow/test/DepositTest.t.sol rename to solidity/deferred-escrow/test/DepositTest.t.sol diff --git a/solidity/packages/deferred-escrow/test/ThawWithdrawTest.t.sol b/solidity/deferred-escrow/test/ThawWithdrawTest.t.sol similarity index 100% rename from solidity/packages/deferred-escrow/test/ThawWithdrawTest.t.sol rename to solidity/deferred-escrow/test/ThawWithdrawTest.t.sol diff --git a/solidity/packages/deferred-escrow/test/TokenCompatibilityTest.t.sol b/solidity/deferred-escrow/test/TokenCompatibilityTest.t.sol similarity index 100% rename from solidity/packages/deferred-escrow/test/TokenCompatibilityTest.t.sol rename to solidity/deferred-escrow/test/TokenCompatibilityTest.t.sol diff --git a/solidity/packages/deferred-escrow/test/ViewFunctionTest.t.sol b/solidity/deferred-escrow/test/ViewFunctionTest.t.sol similarity index 100% rename from solidity/packages/deferred-escrow/test/ViewFunctionTest.t.sol rename to solidity/deferred-escrow/test/ViewFunctionTest.t.sol diff --git a/solidity/packages/deferred-escrow/test/VoucherCollectionTest.t.sol b/solidity/deferred-escrow/test/VoucherCollectionTest.t.sol similarity index 100% rename from solidity/packages/deferred-escrow/test/VoucherCollectionTest.t.sol rename to solidity/deferred-escrow/test/VoucherCollectionTest.t.sol diff --git a/solidity/packages/deferred-escrow/test/mocks/MockERC1271.sol b/solidity/deferred-escrow/test/mocks/MockERC1271.sol similarity index 100% rename from solidity/packages/deferred-escrow/test/mocks/MockERC1271.sol rename to solidity/deferred-escrow/test/mocks/MockERC1271.sol diff --git a/solidity/packages/deferred-escrow/test/mocks/MockERC20.sol b/solidity/deferred-escrow/test/mocks/MockERC20.sol similarity index 100% rename from solidity/packages/deferred-escrow/test/mocks/MockERC20.sol rename to solidity/deferred-escrow/test/mocks/MockERC20.sol diff --git a/solidity/packages/deferred-escrow/test/mocks/MockNonStandardERC20.sol b/solidity/deferred-escrow/test/mocks/MockNonStandardERC20.sol similarity index 100% rename from solidity/packages/deferred-escrow/test/mocks/MockNonStandardERC20.sol rename to solidity/deferred-escrow/test/mocks/MockNonStandardERC20.sol diff --git a/solidity/packages/deferred-escrow/.gitignore b/solidity/packages/deferred-escrow/.gitignore deleted file mode 100644 index e2e047d41f..0000000000 --- a/solidity/packages/deferred-escrow/.gitignore +++ /dev/null @@ -1,19 +0,0 @@ -# Compiler files -cache/ -out/ - -# Ignores development broadcast logs -!/broadcast -/broadcast/*/31337/ -/broadcast/**/dry-run/ - -# Docs (auto-generated) -# docs/ - -# Dotenv file -.env - -# Coverage output -lcov.info - -broadcast/ \ No newline at end of file diff --git a/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md b/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md index d82bc58339..58d27e8f77 100644 --- a/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md +++ b/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md @@ -214,4 +214,8 @@ struct FlushAllAuthorization { While each contract instance operates on a single chain, the design supports multi-chain deployments: - Vouchers include `chainId` for chain-specific validation - Contract will be deployed using Safe Singleton Factory for deterministic addresses across chains -- Cross-chain coordination must be handled at the application layer \ No newline at end of file +- Cross-chain coordination must be handled at the application layer + +### Reference Implementation + +A reference implementation for this contract is provided with this repository, it can be found at [DeferredPaymentEscrow](../../../solidity/deferred-escrow/README.md) \ No newline at end of file From 00136c0d5c4dd6f76fa934298862c718e97cf20a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 29 Sep 2025 18:17:58 -0300 Subject: [PATCH 078/116] docs: add deferred sequencing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- README.md | 45 +++++++++++++++++- specs/schemes/deferred/scheme_deferred_evm.md | 2 +- static/x402-deferred-protocol-flow.png | Bin 0 -> 461147 bytes 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 static/x402-deferred-protocol-flow.png diff --git a/README.md b/README.md index 0fa8852e32..fb81be1fbb 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ It specifies: 5. A REST specification for how a resource server can perform verification and settlement against a remote 3rd party server (`facilitator`) 6. A specification for a `X-PAYMENT-RESPONSE` header that can be used by resource servers to communicate blockchain transactions details to the client in their HTTP response -### V1 Protocol Sequencing +### V1 Protocol Sequencing (`exact` scheme) ![](./static/x402-protocol-flow.png) @@ -94,6 +94,48 @@ The following outlines the flow of a payment using the `x402` protocol. Note tha 12. `Resource server` returns a `200 OK` response to the `Client` with the resource they requested as the body of the HTTP response, and a `X-PAYMENT-RESPONSE` header containing the `Settlement Response` as Base64 encoded JSON if the payment was executed successfully. +### V1 Protocol Sequencing (`deferred` scheme) + +![](./static/x402-deferred-protocol-flow.png) + +The `deferred` scheme modifies slightly the x402 protocol flow to allow for a deferred settlement to happen. The following steps outline the resource request and payment verification flow: + +1. `Client` makes an HTTP request to a `resource server` with the `X-PAYMENT-BUYER` header containing the `Client` address. + +2. `Resource server` retrieves previous voucher history for the `Client`, responds with a `402 Payment Required` status and a `Payment Required Response` JSON object in the response body. The response body contains additional information required for the `deferred` scheme encoded in the `extra` field of the payment requirements, it will contain either a new voucher id for the `Client` to generate or details for the latest voucher for the `Client/Resource server` pair if it exists. + +3. `Client` creates a `Payment Payload` based on the value of the `paymentRequirements.extra` property: + - If there is no previous `Client/Resource server` history, it will instruct the `Client` to create a new voucher as payload. + - Otherwise it will contain the latest voucher for the pair, allowing the `Client` to aggregate payments on top of it before setting it as the payload. + +4. `Client` sends the HTTP request with the `X-PAYMENT` header containing the `Payment Payload` to the resource server. The payload will include: + - the signed voucher (which can be new or an aggregation with a previous one) + - (optionally) A signed deposit authorization. Allows the `facilitator server` to escrow funds on behalf of the `Client`. These are the funds the voucher will be claimed against. + +5. `Resource server` verifies the `Payment Payload` is valid either via local verification or by POSTing the `Payment Payload` and `Payment Requirements` to the `/verify` endpoint of a `facilitator server`. + +6. `Facilitator server` performs verification of the object based on the `scheme` and `network` of the `Payment Payload` and returns a `Verification Response`. + +7. If the `Verification Response` is valid: + - The resource server POSTs the validated voucher back to the `facilitator server` for peristent storage. + - The `facilitator server` will reverify the `Payment Payload` before storing the voucher, which makes the previous verification call optional. + - If a deposit authorization is present the `facilitator server` will execute it. + - Then the resource server performs the work to fulfill the original request. + If the `Verification Response` is invalid: + - the resource server returns a `402 Payment Required` status and a `Payment Required Response` JSON object in the response body. + +8. `Resource server` returns a `200 OK` response to the `Client` with the resource they requested as the body of the HTTP response, and a `X-PAYMENT-RESPONSE` header containing the total outstanding payment that is pending on-chain settlement. + +At this point the `Client` has "payed for" the resource access by means of a signed voucher. The `facilitator server` stores the vouchers which can be redeemed at any time. The settlement sequencing then is as follows: + +1. `Resource server` requests a settlement to happen by POSTing to a special `facilitator server` endpoint. + +2. `Facilitator server` retrieves the voucher to be settled and submits the transaction to the blockchain based on the `scheme` and `network` of the `Payment Payload`. + +3. `Facilitator server` waits for the voucher settlment to be confirmed on the blockchain. + +4. `Facilitator server` returns a `Payment Execution Response` to the resource server. + ### Type Specifications #### Data types @@ -149,6 +191,7 @@ The following outlines the flow of a payment using the `x402` protocol. Note tha // Extra information about the payment details specific to the scheme // For `exact` scheme on a EVM network, expects extra to contain the records `name` and `version` pertaining to asset + // For `deferred` scheme on a EVN network, expects extra to contain the records `type`, `voucher` and `signature` extra: object | null; } ``` diff --git a/specs/schemes/deferred/scheme_deferred_evm.md b/specs/schemes/deferred/scheme_deferred_evm.md index ef9fff49bb..d54287f29d 100644 --- a/specs/schemes/deferred/scheme_deferred_evm.md +++ b/specs/schemes/deferred/scheme_deferred_evm.md @@ -74,6 +74,7 @@ Full `X-PAYMENT` header: ## `paymentRequirements` extra object The `extra` object in the "Payment Required Response" should contain the following fields: +- A `type` field to indicate wether it's a new voucher or an aggregation - If this is a new voucher being created: - `voucher`: A simplified voucher object with: - `id`: The voucher id @@ -81,7 +82,6 @@ The `extra` object in the "Payment Required Response" should contain the followi - If an existing voucher is being aggregated: - `signature`: The signature of the latest voucher corresponding to the given `id` - `voucher`: The latest voucher corresponding to the given `id` -- Additionally a `type` field to indicate wether it's a new voucher or an aggregation Example: diff --git a/static/x402-deferred-protocol-flow.png b/static/x402-deferred-protocol-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..03c43104beddb30eaddd361b23db79f849218868 GIT binary patch literal 461147 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

LKDZtR)_xFM&mS)W`t88TDQ%)F7fVk^c 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

YM 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≧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�GZ*(RAkLQ=7v zB{VEqj%4REOI-E-4V5tdg=vq`#yh%PpLldXL!PLP0|${$j1t2fp@yTF;g8snF)){c z2x{S7bR5#OI{|fB6fES7R=rspJiSxUW?Stf6=7j?d4M?2{=-{n`oO(AO|l|K%a;bX z9;eNhl{+VNgr6Pfwrq|4$Zxk@%#tL;c$&&=bva^fa4dg#oUNH8f!Kg zo_w}e=LdCisO-84AlYPA*_AY`YY2wR!qZQLMA_W4pVaPp%Xl7Pw{EFZ`RRpcJVmo% z$s0e>m~N(O1?t^q;za>@XDr{gg=I1{2NcWVDWl>*I3%Q&Vm&KvR-7_s_Jz2EV+WM|lXM}kW$i@m zUY(1NU^Op94oxYE-n;OfTwX%C1WZols=Dqk{#rA^qsH7-FDo@d-0^9Xp>ls({`T!@ zevx|(#;Kc;Em}Y38}o-~{}dw31Kd$Q%lS%a8p4Fnt~M}tMeQlS>bVfA{~>~5>D ziSt{tYW+gOj6MkiX+FfK9d9ro<;rsVTdT_w!fnG$y5^~A>ubRj@#mBumqKzz#9GVG3QzDFR*M=kQ!goGaew5)jb?>9Ak+PtE zlwr++_naGrqlj0febWJQdr1|3I=YyajAj0;O55(+-%#LDko9*^I3I0d;lXEL**4TiP)mu0OF1dShkl z+DXKJ*aNc`bbLVFN^5B=<&mEC_$X*vC24uyPd$*PQ4_Jd`h$K{Ur`8r**)k~2 zk%$!mpRwfub5mu6lD0`Zk*8F&b9}e4VWso?D~(C*40A8F3i82}7^;`&k&mB+@7O4> zkJM+pv_bWS0dV&`YlRuyaqI&<4uY%5@L{#E+(J+#zKg5Be<3X97#=v@RO+mE$9Yx! zDgKMR1kGEy9-gjq*#;Bi^h*swQdvgr6WWyZa}>c^PhX5QRX|bUtzy;$gB_P$w>B1$ zyzRxCI>0S&_+qF$3UWn{#)=Vcmqil%Z8}vrB40|$H#u~^GhkiqdtEtWUPhZYU^DbF z-cYLd<4d}dP;MQ`to$5uo8GxXmAm&s-J%L#Dt{2)Em3(eNefri56jZ61z-QP-<5~P z92JhzarlwTNhEZSkIGB11p`g3$lg3qWB# zUe-DqyJiSRx0XLt*z9BDe{%UwME9n7?(l>B-4mw4?L&k8ZOFI~jS`c7;L2aru;^VJ z4!yog5N`hQT5y9X=noFbEnI1GsuZHyElq7gH$Al^;2u4QEcdt#752WL8ah#RC?JMM z5Gt9gKq6=P)Q6p0J1c@vQJ(KYhAY!+0Yns&C`XaWjuWFIsHu zlu{WoYS%-A#!pGE_H2qPb7ZCSQUe8LnA>2g^U|E1H}C{6u_gHDcB$}zw%)-gtDc8x z8thr!mBXX``zB0>&wHtNOJFi=2xhBh{-(CFc zwY@0F4Jlbhf6z)7z4;?4Uh;o%e3vZUY_I`4$zZp`eG>1Sxsds z?Wkd%hA>zGq0q$$APcHOjPjhI16;Lm`9uDMhVX->AHKYI=$i!R7r1rTGc$j@toN?u zY)u+?%^VdhrzzgsdtZR@4wbOWdR78q^@sy-4~FMKGDC|h@Gl>V0Wc6{v~0V)tMb!> zz{F^$#kcdX0<#ljy1w(%D=-**D~jw7!;A5KR&)y$ZjFkA0X&}dloOS9oJf7d=G@PkP{>fFv+Z}_m6`uuTdCeW?h z&+%Vz@b_gZG&H5SPN)O%i~ynjaMHw=H)rYHrh6>F@VwZ*o-BZy#}iG?sT-yD)vgX% zMDj`cW~pd*zbaJus&MN?GYd}9dzIA$u5k_ihjrC!Wm|LHGwi$+#;ZM#y>*2c9fv?L z2MzXu2Hu&hekPZvs*m&JQ{FOLe7alZPlPfZk%Uwlt~QrtZ)!T$RV&)~)3O*AxAZVa zyHci??TlAGwgtnqNUF|gGe;Uwq&c5BBU+%cRo*ptIoRnVcfliH<()M(pLCgWndb8L zVggVXy85Gfk*jE=cLA|Q&#Fa5Xg9b8Q?Yp#?R8|=Sy%PmdY}xu+7mK5`}Hh~M&hwS z^U@_P!SSH%m!@iL4I*6;)zem-J5Io8|DgTYEV}z~1ldVAv^y_dJ?%mw!e6qr<6S+Y z6nfS0=`Dm0MQ3+G_4ZBvR78Gf|0SQ95Ax!&jrD#ZH_OhpzGiLHz87k_8UJWTDI_qW zO^BAOlQtqCBHb--juVxzG0?J5McD!E*-WS8 zCcn5~m8-F(oQyX4i@R4Tabm>^aK2DQ8ykfHC}oi=!X73XTl%BRI_dSqsIqfTvP zpi4ey`D)EVS2mZ?db+7{@Fi^%m3yHso$-Qe!t0Y3vn*~zX^dw=L|dmuz_0)?mLWnW z{lqbPWXQ))!#NK;j~X)1Xs(J~)v#S5_DrS|bDL1Fr?5LCN4sm*d;~Rh>)w^cqzR4F zc>|A!GM5IA8JKnT+shPetQIR~&xV@M7goNk=ZbvWRtx6GoVMK_#Tf>Jhw1|V5I~Nd z?6I2CQm>s(aZRviD?P%$v#~l1BDdxdSr_D7WxdauI@`8McKnK*8;{&P*~VyDPQ#GLs~rhF&A zOX_MQMg7i&>&fAE^YPzjh7dLis}1GzWn2SKp%hjE{_-!5IuoIKW1C%y-_ULnY2q;) z9^h7L4)9|kl~fft201(Ef_SDou%J^VndEZz zA|pw(ZBzAm#u3W1@v&V)JDUcc^>kw9YxNvo0$bYV2U%WhqKI(6k7jl&B~{5JFfg+% z{cCgC!qcpDX2Ky=ogQ6*DFKU)6#-9mL{YwqK&?qOWf#l+c#p+4n(^o_VlE(PTl7X~ z>#w$akoN#_nm}Kn;9RN(wN=8LYtO=#$_I;gk!!sh`8|aTuWi@l>PA>t1gnEx={=p& zA}1nTIs-aWEx6uAJ9lmXzuvoD`F&ZMmGr9kdz~H6EyIRoEx}DL1CN{!*1eAlEf7H; zNKRTciL2Ybvn@o0kYA=QirE2|tg&WbB0x_Pq{tBFMIpM~Zfo)1ca=i?WIMIlB0pYi z6cMu;<*<9yg)WSR8=c}NL7#tN(i+gASA!2YNi0c?6+~$X^gk^$xSEqz-7V)SqNVHL zG8|b?);lP}J!!Zkm}m1w`8jNbIjp${a@st0i@&F$28S?Sp_(@b(@BOA6H#Q8q2^JN z_Y<0F((?5e-!%&KFvR{|t6SaWxze@0(-lYR`f+hHEsy2uWK+a35;~89_k`A_QTw_ zRh|j-+Nty)r3TVwz#JjGG+no5fOYUY@wX7NIk^dxcGsX>Z~h`^T={sV4n;b5j>K8MVo zawM0cp;;UtLTEcVab3D>G)Y#tQ`>mOL=$8vik5G=KuI;v@C;Fj)D`4?X>-q@itT2$ zCSr-*x|+u;aa8Iic{=M-RZfP%?+n<}n!xnPZ(FDlTl@%6q0@{xk%8i6DpCwDpk4S$ zJ@^kdqK?{UT{9LV*ysMRDEyPX#vu#+NAhzWM4#5K41ZaYBZdZrLIW7`WO$Z*c|B@U9A}tfe{ZiWfwC8I`7g&F2Wymc8yNMe{b`kD znJuXnO(ZWOF6z)MQ8m}4NoH0&{%2-)B@w?dMdbyeM*7ww35yxN;eJKGx@?wW}hQ6ioWH1+i5aeb?R1K>)T$+`9?5g;yfc!!q8}(L1a*x zy7auuW|{igFH+u!wCy>`Hp+=*r(5O2r)%*OXhV7uT<;CwF6Hfp5a{~$a5mIkcoi8K zXI?%(GP@NRm@F?o9n)~7`i-j$2UCl}>rTE`cIH)f?4{)Q{&ZA(_Q<*Q^)Zjufhw9X zs@>S~*#K8I&y}*+^Q%5`65_Gl^v3H==StSnb-*krmOL(w*hllG`J0BfvUVndQ?e0X zhPM!Rdw)NC&^fID`;6s3TFZiJhOT~5FgIZLIQ3f$SH<{&vesLd`6Z{Y476&$ALD4jC;Oqu}X;TWi5y5F-d7o*}4we9^!&^3zE~V=af|qJpoBX zL~MO|Vm0k1-WmI~yc_Tr5t(}wR1@l$+-VmpS2tK!nD%L)$*)UmD~HXd_l5|BOxfE- zb7G1G(Ie2XpGU>o39f`Iv|`K?S8b((qpVhYgf~@Gi{I&oipSbXZZ{q2rtsQ&Fi!qM~Szj>5g6}7SIP3C@6T_q0%_vUEJf*(AVi3 zFzn_tQvEYCPcgXw5ci?0I1dHT=q$u%Z}1%F)DM^URq{_IWk0P8eMM~my8k}Z%7q#; zy8rWkEgqYE3D!+dTp8lMi7oliqknKIWS=^D4h#sgSlWdHt{mmp)S{8cxU5QA`78Q$-h>KV-CSXrR` z%RpU9_Yzc_G^hjyU0~s~MGQy&UpLU61yEX~>I}z@q99`ZdaGzfoCtM`=aze201jF{ z{xVjEZ=ckMwsVN1lwN^llT``H_X@%{$VvaPoeTpv8Y=Xj9Mym*%ll0Gqe%dj%Hc0# zJV4AnzrvLlSegH!(jm;iI0!@c`=tI(*gZI4X%MrlP|W&l(4gi^Vj&y5rUDK1;bJb> zTj<<1(32aqul-If6q1?s!np^KL;`V~;VqW6wE^}s#jPdYc zo(@+d<5tFeL2WXT5HQO9tP>lN9-pyLHYow8u75KCMfz@Uc)&=+LP}B%1i@7|yIPeU zGeqg@m7khrzTj&d6m?DB1`icWN`lJzmLuGwFb@{vi zKsblx<6HloiDQm}npBM=K962vQ*1IB<~w%VoaGEB?HeXp!m0iaS21PIZ%`?%7-PU- zqoQ2k#hg z2c-~T2|Ow=CCZatuYv5Hp0yuT`E3j;EI?^^irqXfm}!aG*~UU2%9*<>1uefkV*nv7Q=eQWZNBM}iZI^59sGTD|Oz!Np0r4~?b=WCWGrWiLTtt@dr2gZg;!qeE(4%r$e}Y;sm^)n48F@-iPZLa7%1DU>+f*3C&6OynrWq;* z_3ttlUuLZoweo*K!-eLvLp6=75-k)s&1f}Lc=|a{-gCB^?hCIATQ1ks zIPpAK6Y`*z^t=f8!unIF#IqV364M>thp-)8zq@yM#+zeuxh#EOS@M@t>6vJag@IK6 zp$1iG?S0!2^93rD-oSka4QzsTO@pfs4(!0(0%*clN#n$sy(v=TYntSVH{pxq%nu?u z1Fk)Tx;$WfU|Qn(&MRpClo?N+)=){LF^WBDa6atoQ1pjARqO&)+nGna!YaFf&EOhs zsQ^4$egbHmJomv0a9pa~GXiqv``dIRbfPV51=3xdHPhR2)!lAO$;*%ZF!QCrc40BW zcn$l$EZQ)GHjf0Tj-7?`6}Cj|4UKwgFejzhe5&1ic9dC3?jhZk&nFvJw&oI%pY@jg z(vkO1A52hyN1bk=LQ@L$XkfSCLeVp<$?1gl2L=Ha3D6L9nM%*0u<5dg`gL5;$eb$J zcm5e8w=&*SUJqCP=ULk>G_;5be(>0+h?et zj;sCZ3>9?bY1yjiPyJxAEF23z?Sby#gcM8Oz=j=8UzUH^r01b~xXDR_poFjJ$9!?z zUu9okiv3S$I#;hi=%yz>YU92@AkljxJDnPso=`N4$Bg6MbP-|#gBB)VE=5@uC4rtW ztlmqwFgfXdR{=l?3bI^Wv0yNL=v3IDeky?B7Cl^K$JfvKgXVUVh5GN_A8HHTqv;&c zll^u^usble2Ef=?xyjs8=1z$M4lU2nhy&1dPVk}DFQesx$C-pk);qi%nJ-QIFM)Ah zUKoRkQ8@>0BY5aZD8tSWq>tL|E8Ow@n&bdGIB4Fdh1z~?t27>_tM-|GK#6{Pvb)0} z-x$D(b|jCthXWPusBXE4Vaq^wlq2l;`$I5EVs8FK|HUI6hRmZ(cTO~yZ^{*aZ5AHQ z(OGZ#Yc8*C9~e7a+ld35POLkC#cKLY8?qcG?H{Od?dR!%xgZ79~$y_TE zg4pj122y1dpnF*(tG3(1ZbwMpY<>BVO%!8}Vg8A!Ko4~Cd3d4S#rFN-f_u~ieN;gz zB0tjBs_M6J@*s-a9mtj6V54KiO6mu1@Dn)Pb%a484yQV z(15rvU_em>0EC_7G5kG74Zpz$%{36Q%T7~ESl+Y$5hqYtO#jM=XBPAzs<$UimQ;W~ z_o_Es<)_3qXMJqx>3B?@gf`FD&j}j_fXp_A#+W5Agn=wU8PIKAU5-A%&@zO$nCcX` z9HH}0N9aQLQidm2t*3~$TPzM(o{MvjEQ@^;>oIR*k~fz59%BxxO)E+WNuJn8jhAuX!5L+(BT`!7EAv*!G|yvqxXf+zK{L!92H?Nd%EwNUkt}!#&vAUgYE40&|ngI3g);Y zpo9^2pXg516-LqBX_4VvJ8=`6sI18Tv080=vHrDBGJZ#&9gC(rL+3j0*2CE;U$%VH zesRUFiaFY?BiY#L?e$|Mg!P>K=1|-J9G?v;^99ir^~Rt*X!miBisG%I*{}HoHW)&n z*kq8h#m$_^msaAu=;FxC@aSD_ei|d`DjVUmay!d~71oL*B=sEPZq(w|x1#+`Vc4>= zT?r&k;mK3ajlT4S+@@T5%WhyB3G>k0F1+zPNeMZgRJ+Qw8RPeZn{e)!qENc#{fz`=5Ir|o&ACD zxZyig+AjBtBkE{%zoYHZy{~c8GqwO_7-O!#d997LW6J~XQw*+s##vy zE;A=Ec41Nzr}S6W0YYjymMqmJK%e>I6FfEC zRXK{DH^$#_q~^3s>P+1jC$MU~a-CZE_mPhohvMKO#&0?p2=>UPpa%h#`H*hkB}Va{ zGrBtlwl&N z+l`)8fkaId`r(E}+`tD^nA;7-Zdr#I22%}%7K0WEu>Mx zfj@p?saeP>#p;d-kG$cEoZi?|pJu8DnzmnyBpzrvzRs*9TQVT1_h}Gu3a${{y3_WU zpz+AjPdC{C7Qbu4oDUv|!Z>z*c`_KF+iVd%4rckSyX78H;AOy#>^!q)na-;0xLv8G zmOP;-2^0|~H9ARw6Nzz0FqFiY#Y^C*h$h_V+`-B}E-_F7q+4HmSd=8?F-8?Fafi?3 zNp?au`#AdxAsKzn(mson<$GAH2NyrheHtTHXhcDH8d#{Fha zI%j)>QAm6_Au*zlrHS$NlS?^b+z#Kr-#mrha10H^QSgboU?{}B3YCMWZh|O6HJ)Th z<53j%lW!Gy%wM&Dwi54DGddW zo_wwYQ3{&FbmZ)`6>Y&c4FBxm>F-ULEsx9|J0ZX|TgP^UQIItU{R;O$fRqQ6Wr9NvJ+ZE!OqE$R(E z`~SpD^-@o4lgMPx_ z7#mEI1Wn`Fln&u9><FH#7t58khcH%`agaUOgrV*3W>?;Lsrw(7(He6WES4hZ17 zM05~uBwvBu#{JJygc0Mrst#KY>Ofj23zMKgGe6&MT{`lno{~T-v2(r4}UBF4dnmG5%bFcs_fGi>Hhr{S& zp#L(p7^6qwy&yBEK{N9x_<%ggU?{>NT463egcC5c0~QSiau>=M5+5ECg%xFE?!XcR zG``ZnBnvay8=7;3p+cCe(5mF0Npmo29+nQm-3dnre4uUMend~OJ4v8N{ZFlDbPcE; zj?_RQwDfhbKQuc49R>E^H;Z}Z@_RsH@lX6H$7kkJl_Vw?fCefK_oqz$;q)Jx`M^Mx zC2)Q?U-FLmFq*L<&0h+2fF49_Esgg!axhd{egDe;F$)0=Abgq%5F2Uy2nvf5ZE=?V zvB3Q>HV)*}1x)8IY)&M`V8M>E5C;lm&tNDO19};0pI=JB#{sYTJZw&Wz8Gxb09dfk z$%_EfE_kNYkmh2|yRjSPy$*ZU)Bv|0uf( zsHn3pzOu#wwuFL!il~5qNcV_=(h}03Al(u}$0{PNA|Bq1Hk9fXEx3o!eCE0pRW zV*>r8{mkBul<)N>HAqJfbzdG+raP`5ThGPBi!UC0Q;D_Q=LQm z{SjwCBOTspg6C!y*z82Uf~gUl+!0m8iI*R-CjZgV5pbWM)gAqwS^|V8!?q2ZjThhl zK%FUgFhzF5OPB?I;LgYu^jp6XVG)O+4S#)02su=XjAtDF59J8(+`)#o=XwA>)!#Gl ztpH$y$$mzy@8)`}szL$k4s_@Ca1TXPfOPz$U}~;G#rC;$;Sxbk+Z}iN0V# zCrQhkDt_k)U{YtxeFZ!a-Z^Z$avkEpA5!rh57>-F_8{Jcqj(_tGDk1@+A5&;(oLXH zoY#-dcu!HmaT%pwCM&^bp;`{*1bS^;`3CS7W%;y(6Fr!<%siQ&o}^&D`V1tn52`;r zs)0Be6<`1g(%?pPJln$e5$%~vKRE$s2Ppl3AiQsd`#_zF^Q#*H-X}F$WI;xE^5X&L z_+wX&;jJ8fmdb1m#{HPtV27!%LNH9*vgW5#3~X)zO@!bacfnC+!2_n-udJJ^c0ofD zJgUhJOiiq;b}_NVV3baN-r;y}aC3^&&YBVMIFN2^(!?_hO-eO^?4C2Rcr_=6)idTF zi3cbG2Uq3|D2zaM4I>BXLeglDfr&!besjYzA&eyU)|y28Edbr^E&cj7Lm$IHNei`= zLpV6PMe4fr7yi==K~>ED$h{rukz=?*5JfP!>FL5@#x8mW(jDLo<6^La@2}$)#t`3G z@Us_*7B><^tCFyPm8sOp<8edI58+!0wbrQz(e1D%nrZH{|LC_OZUEBbKRt*0=sUJO zZjUmv)BzG0m{<|Nq7oux%>4a@8p2E7W*6KGP#Og^T37tGgx@;yABp9y^>3^NCIEd^ z$nN@ycT9T#_GR4(yy$#8e}CJz#<-CxfZ2t6E2D>!QKNToTn9$m4F5v(#LkvEg~N;>{nU1je`Pn5`ot7?1ABk6EU(Es(dmF9dm=Oh0TqU{9K`v7J_FE z;0bQ6Ve58%CztZ*0dwU43m&-vK?@7UdpXn*WeVBi_80n8y0n}2L+N4X0>WqCO5|{t zZx{ZY8ldJn*+<;-|B=au$sHez=ezJ9TPcqz0z%!{S`74J(|iDQ1NN!m&9ZIcffHUm zQ^&B!aV$#7j&i4bg{k46+?ARGzX)lX1R21gevF>Fy9mm@@5}E^E`W~*dN>g&#$oK+ zMUxx5{GD2YZf+3Z0nZO05MWJwbXS!F*x;|V+H)p|2NWghaU^jLJ6^XlBn46G7vGPU z0{fL^^tiLV-=<`zpx=n7t>0XV0gLWwYUbE+^+7OG87A`M1KOkpPDURB+(&+NZcWHw z_gVhLa>q@_+GIo!GX5 ztZhwguGm+nA#oVs5vc`N6uDBKU@RP8oq<4yQU}T{@*I!I88Sk49=eyQq_s|xA?kRf?E^6@Opy*NbTZP|$?-heZ-EpQPJ-O0B{x!C^or@RSPcO?a-MHzO#LJg7ZG33^V0W95+cQqi zg0UNFu)W|Bqon+giI&1 z*6MG4tum8f$g-aZMSawe;FB)6_nqL9Ww`(7$IRkv37(Su_aOV`ej~{Ck%Tygz5mLs zPZYb&jG#_f>M;uNz$tu&D&)Dh#9Z-DP*9GJ|vaAtN~3xPfB2!o&KkZ)o}fmn#IKrZduLvdpWc4+GXZqN>b*D<4Zg2(YR4TO& zQ1#=AUb&EMzCPPhe1ufhK@0+J=&)m_;Q<&`ogbMj+xR>zR+>2obh`k6AXArRYvBW6 zK^sOqKNG(d3*essNjD18A5~5nq-g8_NZpW=|A_|2Lmv;^aSlnl_WCV)4e0Qey$TSoh+IR<#wiL5S%*2{M|RAN^@GS4-) zmWHDEpHm#5vXE-iEWTa}FiKQTJAxK#g>cY@x8&HXW|cS@GTw?EWB)p*Z+w~Dc2M8= z$#ow-E<4*KF$nnN?vm)&{@3KjmF40Hqs-FjuU()+Q-U8Y_|?)1j8XrndVq@9n{UXt zEU!UO*rvxkq4(*41Ru}&Sk_*1fzWWrSwE96wAwCg>?_teeRB!Y7VR&N2WPL8_I#BP zI!#3hx|5%W(X!@1t%OEsDoO}U3OCZD`{?$Nt8CXDL$1taOU!&)}DVr59Nc|JjvVnR8*!P<6Nq*Ky%1JxAm2^hXaeH$2}O76D98CfjnTp z#k}Bnv1B$tZqURKB{y0_K!UUnIQMOkALAj)W9`jh{uxw)PTD=OI6o6N22Nxk6u3y_)56 z`>x?$zYgWnL0awez~-<3NqRi%kP+(u6=Fs}tNs@+jT)1yg0Wg7&yO1tG8-3F?td_R zO8b)XQwZy>5s@Edg{cV5B1CnYYc9|4v3**N;G*fWTHz|QjY9~9S>=I#Qy;!X18z+K zSdc;nu=&zVW_t3UmM(SjDVu#5`(i<#6EKvy>%X{v_S1SO`E!zcZ&N#mgd0-gv!pV zFR@i^nvqbl{uu5?U&}`$rEa)Vg0)WPXNE8O`Fl|EkzxG+F1de|(H(q*LUi&>wb~aY z6xR|x&0PWX$Lbd^Ju0#?*3G8a?s?z2Kv_5X)WR`SuLaWennT&W)=czFU{-Z%iJh7D zqSV>U*r+KfOgD=E5;1vbfc!#$S4WkGEedmlJ~{Trg!OPpVVnO;PYJ3=ckGr{NXu4p z_}3T1Ino#tE*G2MV`NIq`k1D$xR}OPMMezZ&G+2>y?w27zK%0E`Y!3AOq%;y8v+!j zx_3PX+sC=sR+^?!?R7x&O?0%IZn zVElI?raHw{Ysk1bB^))GUh^`Os{~7hu@Ny*(IUB1vlEC8T87C1!RAx2Gbf zd2Z3JEHxsqr0_0u_62R;$qK4;Fc){NOC;q+>3~asTFvSjr=8V3ahC;84+Jl>)JyaD z0Plq_0Oyh`IcMF!%_O+H{|h0b$1&<#uNXPFQ9Dm~zYmMR+aSRltPn!|> zj>ScBag~wAz5EKcD|`wAdx<*=^)8`5^X4ZdB#oet!E4RjZea7y45N?geL9O%|2jQ@~0+7%L-n z>rCbrINYP1EpJ>StMOrFr1E8~h<$C*jJwrfrM7VMt s-UdznWaXZxe8tNm9kC8& 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%0A%9X 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%0Ad8&lwA0{gMGsNo>$BMt(t}Qr>x(wN57^Kybx(o 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 VkMI-V4}bl2O;Yx9>Lsne{|{+L5Pkpv literal 0 HcmV?d00001 From 12550e9eed8e43a2c0abd0277349c66b38966abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 1 Oct 2025 15:19:08 -0300 Subject: [PATCH 079/116] feat(x402-express): support both facilitator and local voucher stores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-express/src/index.ts | 132 +++++++++++------- 1 file changed, 78 insertions(+), 54 deletions(-) diff --git a/typescript/packages/x402-express/src/index.ts b/typescript/packages/x402-express/src/index.ts index 8749d79540..1749349418 100644 --- a/typescript/packages/x402-express/src/index.ts +++ b/typescript/packages/x402-express/src/index.ts @@ -26,7 +26,6 @@ import { DEFERRRED_SCHEME, DeferredEvmPayloadSchema, EXACT_SCHEME, - DeferredEvmPayloadSignedVoucher, } from "x402/types"; import { useFacilitator } from "x402/verify"; @@ -353,28 +352,29 @@ export function paymentMiddleware( /** * Creates a deferred payment middleware factory for Express. * - * Note: this middleware only performs x402 verification. In the deferred scheme, - * settlement does not happen as part of the x402 resource request handshake. + * Note: this middleware does not perform the x402 settlement step. In the deferred scheme, + * settlement does not happen as part of the x402 resource request handshake, it happens later + * on in a "deferred" way. * - * The middleware requires two server-implemented functions, executed before and after - * x402 verification: - * - retrieveVoucher: Before verification, retrieves the latest voucher for a given - * buyer/seller. Used to determine whether to create a new voucher or aggregate - * into the existing one. - * - storeVoucher: After verification, allows the server to persist the newly created - * voucher. This can be stored locally or via a third-party service. + * The middleware delegates voucher storage to the facilitator but can be configured to store vouchers + * locally on the resource server. The server needs to implement it's own voucher store and expose two + * main functions for the middleware: + * - getAvailableVoucher: Retrieves the latest voucher for a given buyer/seller + * - storeVoucher: Persists newly created vouchers + * + * If `voucherStore` is not provided, voucher storage is delegated to the facilitator. * * @param payTo - The address to receive payments * @param routes - Configuration for protected routes and their payment requirements - * @param getAvailableVoucher - A function to get the latest voucher for a given buyer and seller. Needs to be implemented by the server. - * @param escrow - The escrow address - * @param storeVoucher - A function to store the voucher. Needs to be implemented by the server. + * @param escrow - The escrow contract address * @param facilitator - Optional configuration for the payment facilitator service + * @param voucherStore - Optional voucher storage implementation with `getAvailableVoucher` and `storeVoucher` methods * @returns An Express middleware handler * * @example * ```typescript * // Simple configuration — all endpoints protected by $0.01 of USDC on Base Sepolia + * // Uses facilitator for voucher storage * app.use( * deferredPaymentMiddleware( * '0x123...', // payTo address @@ -382,14 +382,12 @@ export function paymentMiddleware( * price: '$0.01', // USDC amount in dollars * network: 'base-sepolia', * }, - * retrieveVoucher, * '0xescrowAddress...', - * storeVoucher, * // Optional facilitator configuration (defaults to x402.org/facilitator for testnet usage) * ) * ); * - * // Advanced configuration — endpoint-specific requirements & custom facilitator + * // Advanced configuration — custom voucher store and facilitator * app.use( * deferredPaymentMiddleware( * '0x123...', // payTo @@ -402,9 +400,7 @@ export function paymentMiddleware( * }, * }, * }, - * retrieveVoucher, * '0xescrowAddress...', - * storeVoucher, * { * url: 'https://facilitator.example.com', * createAuthHeaders: async () => ({ @@ -413,9 +409,14 @@ export function paymentMiddleware( * }), * }, * { - * cdpClientKey: 'your-cdp-client-key', - * appLogo: '/images/logo.svg', - * appName: 'My App', + * getAvailableVoucher: async (buyer, seller) => { + * // Custom implementation to retrieve voucher + * return await db.getVoucher(buyer, seller); + * }, + * storeVoucher: async (voucher) => { + * // Custom implementation to store voucher + * await db.saveVoucher(voucher); + * }, * } * ) * ); @@ -424,16 +425,27 @@ export function paymentMiddleware( export function deferredPaymentMiddleware( payTo: Address, routes: RoutesConfig, - getAvailableVoucher: ( - buyer: string, - seller: string, - ) => Promise, escrow: Address, - storeVoucher: (voucher: DeferredEvmPayloadSignedVoucher) => Promise, facilitator?: FacilitatorConfig, + voucherStore?: Pick< + InstanceType, + "getAvailableVoucher" | "storeVoucher" + >, ) { - const { verify } = useFacilitator(facilitator); const x402Version = 1; + const { verify, deferred: deferredFacilitator } = useFacilitator(facilitator); + + // Default voucher store is the facilitator + const facilitatorVoucherStore = { + getAvailableVoucher: async (buyer: string, seller: string) => { + const result = await deferredFacilitator.getAvailableVoucher(buyer, seller); + if ("error" in result) { + throw new Error(result.error); + } + return result; + }, + storeVoucher: deferredFacilitator.storeVoucher, + }; // Pre-compile route patterns to regex and extract verbs const routePatterns = computeRoutePatterns(routes); @@ -481,7 +493,9 @@ export function deferredPaymentMiddleware( paymentBuyer as `0x${string}` | undefined, payTo, escrow, - getAvailableVoucher, + voucherStore + ? voucherStore.getAvailableVoucher + : facilitatorVoucherStore.getAvailableVoucher, ), }, ]; @@ -529,38 +543,48 @@ export function deferredPaymentMiddleware( return; } - try { - const response = await verify(decodedPayment, selectedPaymentRequirements); - if (!response.isValid) { + // At this point x402 protocol requires POSTing to /verify the payment requirements + // If we are using the facilitator's voucher store then when posting to store the voucher the facilitator + // will already perform the same verification. So if we use the facilitator's voucher store we can skip /verify. + if (voucherStore) { + try { + // POST /verify to facilitator + const response = await verify(decodedPayment, selectedPaymentRequirements); + if (!response.isValid) { + res.status(402).json({ + x402Version, + error: response.invalidReason, + accepts: toJsonSafe(paymentRequirements), + payer: response.payer, + }); + return; + } + + // Store voucher locally + const { voucher, signature } = DeferredEvmPayloadSchema.parse(decodedPayment.payload); + await voucherStore.storeVoucher({ ...voucher, signature }); + } catch (error) { + console.log(error); res.status(402).json({ x402Version, - error: response.invalidReason, + error, + accepts: toJsonSafe(paymentRequirements), + }); + return; + } + } else { + try { + // skip POST /verify and store voucher in facilitator + await facilitatorVoucherStore.storeVoucher(decodedPayment, selectedPaymentRequirements); + } catch (error) { + console.error(error); + res.status(402).json({ + x402Version, + error, accepts: toJsonSafe(paymentRequirements), - payer: response.payer, }); return; } - } catch (error) { - console.log(error); - res.status(402).json({ - x402Version, - error, - accepts: toJsonSafe(paymentRequirements), - }); - return; - } - - try { - const { voucher, signature } = DeferredEvmPayloadSchema.parse(decodedPayment.payload); - await storeVoucher({ ...voucher, signature }); - } catch (error) { - console.error(error); - res.status(402).json({ - x402Version, - error, - accepts: toJsonSafe(paymentRequirements), - }); - return; } // Proceed to the next middleware or route handler From 2600ac73756194bca9a3f00eeaf75214e7fee48a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 1 Oct 2025 16:21:04 -0300 Subject: [PATCH 080/116] feat(examples): add deferred routes to example resource server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../typescript/servers/express/.env-local | 1 + .../typescript/servers/express/deferred.ts | 9 +--- examples/typescript/servers/express/index.ts | 42 ++++++++++++++++++- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/examples/typescript/servers/express/.env-local b/examples/typescript/servers/express/.env-local index 9e299111bc..cc6ef43155 100644 --- a/examples/typescript/servers/express/.env-local +++ b/examples/typescript/servers/express/.env-local @@ -1,6 +1,7 @@ FACILITATOR_URL=https://x402.org/facilitator NETWORK=base-sepolia ADDRESS= +DEFERRED_ESCROW=0xF1308b39EdB10E5163581C1f8D0Bf8E26404A11f # required if using the Base mainnet facilitator CDP_API_KEY_ID="Coinbase Developer Platform Key" diff --git a/examples/typescript/servers/express/deferred.ts b/examples/typescript/servers/express/deferred.ts index 8da31e31b9..840a732e4f 100644 --- a/examples/typescript/servers/express/deferred.ts +++ b/examples/typescript/servers/express/deferred.ts @@ -4,12 +4,10 @@ * X402 Deferred Payment Joke Server - Simplified Example * * This is a minimal Express server demonstrating X402 deferred payment integration - * using the standardized @project-a2ap/gateway client package. + * */ import express from "express"; -import { GatewayClient } from "@x402/gateway/client"; -import { deferred } from "x402/schemes"; // Configuration const PORT = parseInt(process.env.PORT || "3002"); @@ -18,11 +16,6 @@ const PAYMENT_PRICE = process.env.PAYMENT_PRICE || "0.00001"; const PAYMENT_NETWORK = (process.env.PAYMENT_NETWORK as "base-sepolia" | "base") || "base-sepolia"; const PAYMENT_SELLER = process.env.PAYMENT_SELLER || "0xC93d37AD45c907eE1b27a02b2E1bd823BA9D379C"; -// Initialize Gateway client -const gatewayClient = new GatewayClient({ - baseUrl: GATEWAY_URL, -}); - // Simple joke collections const FREE_JOKES = [ "Why don't scientists trust atoms? Because they make up everything!", diff --git a/examples/typescript/servers/express/index.ts b/examples/typescript/servers/express/index.ts index 37e35d27ce..93c2b22d77 100644 --- a/examples/typescript/servers/express/index.ts +++ b/examples/typescript/servers/express/index.ts @@ -1,10 +1,16 @@ import { config } from "dotenv"; import express from "express"; -import { paymentMiddleware, Resource, type SolanaAddress } from "x402-express"; +import { + paymentMiddleware, + deferredPaymentMiddleware, + Resource, + type SolanaAddress, +} from "x402-express"; config(); const facilitatorUrl = process.env.FACILITATOR_URL as Resource; const payTo = process.env.ADDRESS as `0x${string}` | SolanaAddress; +const deferredEscrow = process.env.DEFERRED_ESCROW as `0x${string}`; if (!facilitatorUrl || !payTo) { console.error("Missing required environment variables"); @@ -13,6 +19,7 @@ if (!facilitatorUrl || !payTo) { const app = express(); +// Exact scheme content app.use( paymentMiddleware( payTo, @@ -49,6 +56,25 @@ app.use( ), ); +// Deferred scheme content +if (deferredEscrow) { + app.use( + deferredPaymentMiddleware( + payTo as `0x${string}`, + { + "/deferred/*": { + price: "$0.001", + network: "base-sepolia", + }, + }, + deferredEscrow, + { + url: facilitatorUrl, + }, + ), + ); +} + app.get("/weather", (req, res) => { res.send({ report: { @@ -64,6 +90,20 @@ app.get("/premium/content", (req, res) => { }); }); +app.get("/free", (req, res) => { + res.send({ + content: "This is free content", + }); +}); + +if (deferredEscrow) { + app.get("/deferred/content", (req, res) => { + res.send({ + content: "This is premium content via deferred scheme", + }); + }); +} + app.listen(4021, () => { console.log(`Server listening at http://localhost:${4021}`); }); From ff7d38b71d5f9cf399cd59d16f8eb7ba95e4d35a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 1 Oct 2025 17:19:00 -0300 Subject: [PATCH 081/116] fix: ensure correct headers are set and returned in deferred MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-axios/src/index.ts | 13 ++----- typescript/packages/x402-express/src/index.ts | 36 +++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/typescript/packages/x402-axios/src/index.ts b/typescript/packages/x402-axios/src/index.ts index ee9cfc0fa3..3520d86b16 100644 --- a/typescript/packages/x402-axios/src/index.ts +++ b/typescript/packages/x402-axios/src/index.ts @@ -18,7 +18,6 @@ import { EXACT_SCHEME, PaymentRequirements, PaymentRequirementsSchema, - Wallet, } from "x402/types"; /** @@ -136,12 +135,12 @@ export function withPaymentInterceptor( */ export function withDeferredPaymentInterceptor( axiosClient: AxiosInstance, - walletClient: Wallet, + walletClient: Signer | MultiNetworkSigner, paymentRequirementsSelector: PaymentRequirementsSelector = selectPaymentRequirements, ) { // intercept the request to send a `X-PAYMENT-BUYER` header with each request axiosClient.interceptors.request.use( - async request => { + request => { const buyer = (walletClient as LocalAccount).address || (walletClient as Client).account?.address; if (buyer) { @@ -150,13 +149,7 @@ export function withDeferredPaymentInterceptor( return request; }, - async (error: AxiosError) => error, - { - synchronous: true, - runWhen() { - return true; - }, - }, + error => Promise.reject(error), ); axiosClient.interceptors.response.use( response => response, diff --git a/typescript/packages/x402-express/src/index.ts b/typescript/packages/x402-express/src/index.ts index 1749349418..d00cf43f78 100644 --- a/typescript/packages/x402-express/src/index.ts +++ b/typescript/packages/x402-express/src/index.ts @@ -26,6 +26,7 @@ import { DEFERRRED_SCHEME, DeferredEvmPayloadSchema, EXACT_SCHEME, + SettleResponse, } from "x402/types"; import { useFacilitator } from "x402/verify"; @@ -587,8 +588,43 @@ export function deferredPaymentMiddleware( } } + /* eslint-disable @typescript-eslint/no-explicit-any */ + type EndArgs = + | [cb?: () => void] + | [chunk: any, cb?: () => void] + | [chunk: any, encoding: BufferEncoding, cb?: () => void]; + /* eslint-enable @typescript-eslint/no-explicit-any */ + + const originalEnd = res.end.bind(res); + let endArgs: EndArgs | null = null; + + res.end = function (...args: EndArgs) { + endArgs = args; + return res; // maintain correct return type + }; + // Proceed to the next middleware or route handler next(); + + // If the response from the protected route is >= 400, do not set X-PAYMENT-RESPONSE + if (res.statusCode >= 400) { + res.end = originalEnd; + if (endArgs) { + originalEnd(...(endArgs as Parameters)); + } + return; + } + + // Return with X-PAYMENT-RESPONSE + const responseHeader = settleResponseHeader({ + success: true, + } as SettleResponse); + res.setHeader("X-PAYMENT-RESPONSE", responseHeader); + + res.end = originalEnd; + if (endArgs) { + originalEnd(...(endArgs as Parameters)); + } }; } From 76583d583b17671c8f22917539f74fc80bc5dff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 1 Oct 2025 17:19:32 -0300 Subject: [PATCH 082/116] feat(examples): add deferred client examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- examples/typescript/clients/axios/deferred.ts | 47 +++ .../typescript/clients/axios/package.json | 3 +- .../typescript/clients/axios/tsconfig.json | 11 +- .../typescript/servers/express/deferred.ts | 356 ------------------ 4 files changed, 57 insertions(+), 360 deletions(-) create mode 100644 examples/typescript/clients/axios/deferred.ts delete mode 100644 examples/typescript/servers/express/deferred.ts diff --git a/examples/typescript/clients/axios/deferred.ts b/examples/typescript/clients/axios/deferred.ts new file mode 100644 index 0000000000..30dec7bbe3 --- /dev/null +++ b/examples/typescript/clients/axios/deferred.ts @@ -0,0 +1,47 @@ +import axios from "axios"; +import { config } from "dotenv"; +import { + withDeferredPaymentInterceptor, + decodeXPaymentResponse, + createSigner, + type Hex, +} from "x402-axios"; + +config(); + +const privateKey = process.env.PRIVATE_KEY as Hex | string; +const baseURL = process.env.RESOURCE_SERVER_URL as string; // e.g. https://example.com +const endpointPath = process.env.ENDPOINT_PATH as string; // e.g. /weather + +if (!baseURL || !privateKey || !endpointPath) { + console.error("Missing required environment variables"); + process.exit(1); +} + +/** + * This example shows how to use the x402-axios package to make a request to a resource server that requires a payment + * using deferred scheme. + * + * To run this example, you need to set the following environment variables: + * - PRIVATE_KEY: The private key of the signer (buyer) + * - RESOURCE_SERVER_URL: The URL of the resource server + * - ENDPOINT_PATH: The path of the endpoint to call on the resource server + * + */ +async function main(): Promise { + const signer = await createSigner("base-sepolia", privateKey); + const api = withDeferredPaymentInterceptor( + axios.create({ + baseURL, + }), + signer, + ); + + const response = await api.get(endpointPath); + console.log(response.data); + + const paymentResponse = decodeXPaymentResponse(response.headers["x-payment-response"]); + console.log(paymentResponse); +} + +main(); diff --git a/examples/typescript/clients/axios/package.json b/examples/typescript/clients/axios/package.json index 8d2f89bdb8..998bdaabd8 100644 --- a/examples/typescript/clients/axios/package.json +++ b/examples/typescript/clients/axios/package.json @@ -4,6 +4,7 @@ "type": "module", "scripts": { "dev": "tsx index.ts", + "dev:deferred": "tsx deferred.ts", "dev:multi-network-signer": "tsx multi-network-signer.ts", "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", @@ -27,4 +28,4 @@ "tsx": "^4.7.0", "typescript": "^5.3.0" } -} +} \ No newline at end of file diff --git a/examples/typescript/clients/axios/tsconfig.json b/examples/typescript/clients/axios/tsconfig.json index 78f9479b1b..227beb61c4 100644 --- a/examples/typescript/clients/axios/tsconfig.json +++ b/examples/typescript/clients/axios/tsconfig.json @@ -9,7 +9,12 @@ "strict": true, "resolveJsonModule": true, "baseUrl": ".", - "types": ["node"] + "types": [ + "node" + ] }, - "include": ["index.ts"] -} + "include": [ + "index.ts", + "deferred.ts" + ] +} \ No newline at end of file diff --git a/examples/typescript/servers/express/deferred.ts b/examples/typescript/servers/express/deferred.ts deleted file mode 100644 index 840a732e4f..0000000000 --- a/examples/typescript/servers/express/deferred.ts +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env node - -/** - * X402 Deferred Payment Joke Server - Simplified Example - * - * This is a minimal Express server demonstrating X402 deferred payment integration - * - */ - -import express from "express"; - -// Configuration -const PORT = parseInt(process.env.PORT || "3002"); -const GATEWAY_URL = process.env.GATEWAY_URL || "http://localhost:3001"; -const PAYMENT_PRICE = process.env.PAYMENT_PRICE || "0.00001"; -const PAYMENT_NETWORK = (process.env.PAYMENT_NETWORK as "base-sepolia" | "base") || "base-sepolia"; -const PAYMENT_SELLER = process.env.PAYMENT_SELLER || "0xC93d37AD45c907eE1b27a02b2E1bd823BA9D379C"; - -// Simple joke collections -const FREE_JOKES = [ - "Why don't scientists trust atoms? Because they make up everything!", - "Why did the scarecrow win an award? He was outstanding in his field!", - "Why don't eggs tell jokes? They'd crack each other up!", - "What do you call a fake noodle? An impasta!", - "Why did the math book look so sad? Because it was full of problems!", -]; - -const PREMIUM_JOKES = [ - "Why don't programmers like nature? It has too many bugs!", - "How many programmers does it take to change a light bulb? None – that's a hardware problem!", - "Why do Java developers wear glasses? Because they don't see sharp!", - "What's a computer's favorite beat? An algo-rhythm!", - "Why did the developer go broke? Because he used up all his cache!", - "How do you comfort a JavaScript bug? You console it!", - "What do you call a programmer from Finland? Nerdic!", - "Why do programmers prefer dark mode? Because light attracts bugs!", -]; - -// Helper functions -/** - * Get a random joke from the list - * - * @param jokes - The list of jokes to choose from - * @returns A random joke from the list - */ -function getRandomJoke(jokes: string[]): string { - return jokes[Math.floor(Math.random() * jokes.length)]; -} - -/** - * Convert a price in dollars to atomic units - * - * @param priceInDollars - The price in dollars - * @returns The price in atomic units - */ -function priceToAtomicUnits(priceInDollars: string): string { - const priceFloat = parseFloat(priceInDollars); - const atomicUnits = Math.floor(priceFloat * 1000000); // USDC has 6 decimals - return atomicUnits.toString(); -} - -// Create Express app -const app = express(); - -// Basic middleware -app.use(express.json()); -app.use(express.urlencoded({ extended: true })); - -// Add request logging -app.use((req, res, next) => { - console.log(`${new Date().toISOString()} ${req.method} ${req.path}`); - next(); -}); - -// Routes - -// Root endpoint - Server info -app.get("/", (req, res) => { - res.json({ - name: "X402 Deferred Payment Joke Server", - version: "1.0.0", - description: "A simple example demonstrating X402 deferred payments", - endpoints: { - freeJoke: "/free-joke", - premiumJoke: "/premium-joke", - health: "/health", - }, - payment: { - network: PAYMENT_NETWORK, - price: `$${PAYMENT_PRICE}`, - seller: PAYMENT_SELLER, - }, - }); -}); - -// Health check -app.get("/health", (_req, res) => { - void (async () => { - try { - // Simple fetch to check gateway connectivity - const response = await fetch(`${GATEWAY_URL}/health`, { - method: "GET", - signal: AbortSignal.timeout(5000), - }); - - const gatewayHealthy = response.ok; - - res.status(gatewayHealthy ? 200 : 503).json({ - status: gatewayHealthy ? "healthy" : "unhealthy", - gateway: { - url: GATEWAY_URL, - status: gatewayHealthy ? "connected" : "disconnected", - }, - timestamp: new Date().toISOString(), - }); - } catch (error: unknown) { - res.status(503).json({ - status: "unhealthy", - gateway: { - url: GATEWAY_URL, - status: "error", - error: error instanceof Error ? error.message : "Unknown error", - }, - timestamp: new Date().toISOString(), - }); - } - })(); -}); - -// Free joke endpoint -app.get("/free-joke", (req, res) => { - const joke = getRandomJoke(FREE_JOKES); - res.json({ - joke, - type: "free", - timestamp: new Date().toISOString(), - }); -}); - -// Premium joke endpoint (requires payment) -app.get("/premium-joke", (req, res) => { - void (async () => { - try { - const paymentHeader = req.header("X-Payment"); - - // Check for payment header - if (!paymentHeader) { - return res.status(402).json({ - error: "Payment required", - code: "PAYMENT_REQUIRED", - x402Version: 1, - accepts: [ - { - scheme: "deferred", - network: PAYMENT_NETWORK, - maxAmountRequired: priceToAtomicUnits(PAYMENT_PRICE), - resource: `${req.protocol}://${req.get("host")}${req.originalUrl}`, - description: `Premium joke access - $${PAYMENT_PRICE}`, - mimeType: "application/json", - payTo: PAYMENT_SELLER, - maxTimeoutSeconds: 300, - asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", - extra: { - type: "new", - voucher: { - id: `0x${Date.now().toString(16)}${Math.random().toString(16).slice(2)}`.padEnd( - 66, - "0", - ), - escrow: "0x1a9ea876cfe472514967d2e5cf326fb49dc68559", // TODO: Update with real escrow - }, - }, - }, - ], - timestamp: new Date().toISOString(), - }); - } - - // Decode payment - let decodedPayment; - try { - decodedPayment = deferred.evm.decodePayment(paymentHeader); - } catch (error) { - return res.status(400).json({ - error: "Invalid payment format", - code: "INVALID_PAYMENT", - details: error instanceof Error ? error.message : "Payment decoding failed", - timestamp: new Date().toISOString(), - }); - } - - // Verify scheme - if (decodedPayment.scheme !== "deferred") { - return res.status(400).json({ - error: `Invalid payment scheme. Expected 'deferred', got '${decodedPayment.scheme}'`, - code: "INVALID_SCHEME", - timestamp: new Date().toISOString(), - }); - } - - // Create payment requirements for Gateway verification - const paymentRequirements = { - scheme: "deferred" as const, - network: PAYMENT_NETWORK, - maxAmountRequired: priceToAtomicUnits(PAYMENT_PRICE), - resource: `${req.protocol}://${req.get("host")}${req.originalUrl}`, - description: `Premium joke access - $${PAYMENT_PRICE}`, - mimeType: "application/json", - payTo: PAYMENT_SELLER, - maxTimeoutSeconds: 300, - asset: - PAYMENT_NETWORK === "base-sepolia" - ? "0x036CbD53842c5426634e7929541eC2318f3dCF7e" - : "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", - extra: { - type: "new" as const, - voucher: { - id: `0x${Date.now().toString(16)}${Math.random().toString(16).slice(2)}`.padEnd( - 66, - "0", - ), - escrow: "0x0000000000000000000000000000000000000000", - }, - }, - }; - - // Verify payment with Gateway - console.log("Verifying payment with Gateway..."); - const verificationResult = await gatewayClient.verify(decodedPayment, paymentRequirements); - - if (!verificationResult.valid) { - return res.status(402).json({ - error: "Payment verification failed", - code: "VERIFICATION_FAILED", - details: verificationResult.error, - timestamp: new Date().toISOString(), - }); - } - - // Payment verified successfully - console.log("Payment verified successfully:", { - isNewVoucher: verificationResult.gatewayDetails?.isNewVoucher, - details: - typeof verificationResult.gatewayDetails?.details === "string" - ? verificationResult.gatewayDetails?.details - : JSON.stringify(verificationResult.gatewayDetails?.details) || "No details provided", - }); - - // Return premium joke - const joke = getRandomJoke(PREMIUM_JOKES); - res.json({ - joke, - type: "premium", - price: `$${PAYMENT_PRICE}`, - payment: { - verified: true, - isNewVoucher: verificationResult.gatewayDetails?.isNewVoucher, - }, - timestamp: new Date().toISOString(), - }); - } catch (error: unknown) { - console.error("Premium joke endpoint error:", error); - res.status(500).json({ - error: "Internal server error", - code: "INTERNAL_ERROR", - details: error instanceof Error ? error.message : "Unknown error", - timestamp: new Date().toISOString(), - }); - } - })(); -}); - -// 404 handler -app.use((req, res) => { - res.status(404).json({ - error: "Not found", - code: "NOT_FOUND", - path: req.path, - timestamp: new Date().toISOString(), - }); -}); - -// Error handler -app.use((error: Error, req: express.Request, res: express.Response) => { - console.error("Unhandled error:", error); - res.status(500).json({ - error: "Internal server error", - code: "INTERNAL_ERROR", - timestamp: new Date().toISOString(), - }); -}); - -// Start server -/** - * Start the server - */ -async function startServer() { - try { - // Check Gateway connection on startup - console.log("🔍 Checking Gateway connection..."); - try { - const response = await fetch(`${GATEWAY_URL}/health`, { - method: "GET", - signal: AbortSignal.timeout(5000), - }); - if (response.ok) { - console.log("✅ Gateway connection verified"); - } else { - console.log("⚠️ Gateway connection failed - server will still start"); - } - } catch { - console.log("⚠️ Gateway connection error - server will still start"); - } - - // Start Express server - const server = app.listen(PORT, () => { - console.log(`🎭 X402 Deferred Payment Joke Server started`); - console.log(`📍 Server: http://localhost:${PORT}`); - console.log(`🌐 Network: ${PAYMENT_NETWORK}`); - console.log(`💰 Price: $${PAYMENT_PRICE}`); - console.log(`🔗 Gateway: ${GATEWAY_URL}`); - console.log(`🔗 Seller: ${PAYMENT_SELLER}`); - console.log(""); - console.log("Available endpoints:"); - console.log(` GET / - Server info`); - console.log(` GET /health - Health check`); - console.log(` GET /free-joke - Get a free joke`); - console.log(` GET /premium-joke - Get a premium joke (requires X-Payment header)`); - console.log(""); - console.log(`Try: curl http://localhost:${PORT}/free-joke`); - }); - - // Graceful shutdown - const gracefulShutdown = (signal: string) => { - console.log(`\n🛑 Received ${signal}. Shutting down gracefully...`); - server.close(() => { - console.log("✅ Server closed"); - process.exit(0); - }); - }; - - process.on("SIGTERM", () => gracefulShutdown("SIGTERM")); - process.on("SIGINT", () => gracefulShutdown("SIGINT")); - } catch (error) { - console.error("❌ Failed to start server:", error); - process.exit(1); - } -} - -// Start server if this file is run directly -if (import.meta.url === `file://${process.argv[1]}`) { - void startServer(); -} - -// Export for testing -export { app, startServer }; From a11b7858ee2ef3f050bad80138151627ffbd4050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 2 Oct 2025 14:41:33 -0300 Subject: [PATCH 083/116] feat(examples): add deferred facilitator example using in memory voucher store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- examples/typescript/clients/axios/deferred.ts | 8 + examples/typescript/facilitator/.env-local | 5 +- examples/typescript/facilitator/index.ts | 138 ++- examples/typescript/facilitator/package.json | 7 +- examples/typescript/pnpm-lock.yaml | 1101 +++++++++-------- .../scheme_deferred_evm_facilitator.md | 76 +- typescript/packages/x402-express/src/index.ts | 3 + .../x402/src/schemes/deferred/evm/index.ts | 1 + 8 files changed, 764 insertions(+), 575 deletions(-) diff --git a/examples/typescript/clients/axios/deferred.ts b/examples/typescript/clients/axios/deferred.ts index 30dec7bbe3..8174a6284b 100644 --- a/examples/typescript/clients/axios/deferred.ts +++ b/examples/typescript/clients/axios/deferred.ts @@ -40,6 +40,14 @@ async function main(): Promise { const response = await api.get(endpointPath); console.log(response.data); + try { + const xPaymentHeader = response.config.headers["X-PAYMENT"]; + const paymentPayload = JSON.parse(Buffer.from(xPaymentHeader, "base64").toString("utf-8")); + console.log("Deferred voucher details:"); + console.log(paymentPayload.payload.voucher); + } catch (error) { + console.error(error); + } const paymentResponse = decodeXPaymentResponse(response.headers["x-payment-response"]); console.log(paymentResponse); } diff --git a/examples/typescript/facilitator/.env-local b/examples/typescript/facilitator/.env-local index f40aacde60..94c8b4ddc9 100644 --- a/examples/typescript/facilitator/.env-local +++ b/examples/typescript/facilitator/.env-local @@ -1,2 +1,3 @@ -PRIVATE_KEY= -PORT=3002 +EVM_PRIVATE_KEY= +SVM_PRIVATE_KEY= +PORT=3000 diff --git a/examples/typescript/facilitator/index.ts b/examples/typescript/facilitator/index.ts index 98a7e1aefd..cb65e01342 100644 --- a/examples/typescript/facilitator/index.ts +++ b/examples/typescript/facilitator/index.ts @@ -15,7 +15,11 @@ import { ConnectedClient, SupportedPaymentKind, isSvmSignerWallet, + evm, + X402RequestSchema, + DeferredEvmPayloadSchema, } from "x402/types"; +import { deferred } from "x402/schemes"; config(); @@ -32,6 +36,9 @@ const app = express(); // Configure express to parse JSON bodies app.use(express.json()); +// Initialize the in-memory voucher store for deferred payments +const voucherStore = new deferred.evm.InMemoryVoucherStore(); + type VerifyRequest = { paymentPayload: PaymentPayload; paymentRequirements: PaymentRequirements; @@ -71,7 +78,9 @@ app.post("/verify", async (req: Request, res: Response) => { } // verify - const valid = await verify(client, paymentPayload, paymentRequirements); + const valid = await verify(client, paymentPayload, paymentRequirements, { + deferred: { voucherStore }, + }); res.json(valid); } catch (error) { console.error("error", error); @@ -93,13 +102,20 @@ app.get("/settle", (req: Request, res: Response) => { app.get("/supported", async (req: Request, res: Response) => { let kinds: SupportedPaymentKind[] = []; - // evm + // evm exact if (EVM_PRIVATE_KEY) { kinds.push({ x402Version: 1, scheme: "exact", network: "base-sepolia", }); + + // evm deferred + kinds.push({ + x402Version: 1, + scheme: "deferred", + network: "base-sepolia", + }); } // svm @@ -138,7 +154,9 @@ app.post("/settle", async (req: Request, res: Response) => { } // settle - const response = await settle(signer, paymentPayload, paymentRequirements); + const response = await settle(signer, paymentPayload, paymentRequirements, { + deferred: { voucherStore }, + }); res.json(response); } catch (error) { console.error("error", error); @@ -146,6 +164,120 @@ app.post("/settle", async (req: Request, res: Response) => { } }); +// Deferred scheme endpoints + +// GET /deferred/vouchers/:id +app.get("/deferred/vouchers/:id", async (req: Request, res: Response) => { + try { + const { id } = req.params; + const vouchers = await voucherStore.getVoucherSeries(id, {}); + res.json(vouchers); + } catch (error) { + console.error("error", error); + res.status(400).json({ error: "Invalid request" }); + } +}); + +// GET /deferred/vouchers/available/:buyer/:seller +app.get("/deferred/vouchers/available/:buyer/:seller", async (req: Request, res: Response) => { + try { + const { buyer, seller } = req.params; + const voucher = await voucherStore.getAvailableVoucher(buyer, seller); + + if (!voucher) { + return res.status(404).json({ error: "No vouchers available for this buyer-seller pair" }); + } + + res.json(voucher); + } catch (error) { + console.error("error", error); + res.status(400).json({ error: "Invalid request" }); + } +}); + +// POST /deferred/vouchers +app.post("/deferred/vouchers", async (req: Request, res: Response) => { + try { + const { paymentPayload, paymentRequirements } = X402RequestSchema.parse(req.body); + + // Verify the voucher + const client = evm.createConnectedClient(paymentPayload.network); + const verifyResponse = await verify(client, paymentPayload, paymentRequirements, { + deferred: { voucherStore }, + }); + + if (!verifyResponse.isValid) { + return res.status(400).json(verifyResponse); + } + + // Extract and store the voucher + const { signature, voucher } = DeferredEvmPayloadSchema.parse(paymentPayload.payload); + const signedVoucher = { ...voucher, signature }; + const result = await voucherStore.storeVoucher(signedVoucher); + + if (!result.success) { + return res.status(400).json({ + error: result.error ?? "Unknown voucher storage error", + details: { voucher: signedVoucher }, + }); + } + + res.status(201).json(signedVoucher); + } catch (error) { + console.error("error", error); + res.status(400).json({ error: "Invalid request" }); + } +}); + +// POST /deferred/vouchers/:id/:nonce/settle +app.post("/deferred/vouchers/:id/:nonce/settle", async (req: Request, res: Response) => { + try { + const { id, nonce } = req.params; + const nonceNum = parseInt(nonce, 10); + + if (isNaN(nonceNum)) { + return res.status(400).json({ success: false, error: "Invalid nonce" }); + } + + const voucher = await voucherStore.getVoucher(id, nonceNum); + if (!voucher) { + return res.status(404).json({ success: false, error: "Voucher not found" }); + } + + // Get the signer for the voucher's network + const signer = evm.createSigner("base-sepolia", EVM_PRIVATE_KEY as `0x${string}`); + + // Extract signature and voucher data + const { signature, ...voucherData } = voucher; + + // Settle the voucher + const response = await deferred.evm.settleVoucher(signer, voucherData, signature, voucherStore); + + if (!response.success) { + return res.status(400).json({ + success: false, + error: response.errorReason || "Settlement failed", + }); + } + + res.json({ + success: true, + transactionHash: response.transaction, + network: response.network || "base-sepolia", + }); + } catch (error) { + console.error("error", error); + res.status(400).json({ success: false, error: `Settlement failed: ${error}` }); + } +}); + app.listen(process.env.PORT || 3000, () => { console.log(`Server listening at http://localhost:${process.env.PORT || 3000}`); + + console.log( + `For deferred voucher history: GET http://localhost:${process.env.PORT || 3000}/deferred/vouchers/:id`, + ); + console.log( + `To settle a deferred voucher: POST http://localhost:${process.env.PORT || 3000}/deferred/vouchers/:id/:nonce/settle`, + ); }); diff --git a/examples/typescript/facilitator/package.json b/examples/typescript/facilitator/package.json index ad7e820081..f79e7749ec 100644 --- a/examples/typescript/facilitator/package.json +++ b/examples/typescript/facilitator/package.json @@ -17,12 +17,13 @@ }, "devDependencies": { "@eslint/js": "^9.24.0", - "eslint": "^9.24.0", - "eslint-plugin-jsdoc": "^50.6.9", - "eslint-plugin-prettier": "^5.2.6", + "@types/express": "^5.0.3", "@typescript-eslint/eslint-plugin": "^8.29.1", "@typescript-eslint/parser": "^8.29.1", + "eslint": "^9.24.0", "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jsdoc": "^50.6.9", + "eslint-plugin-prettier": "^5.2.6", "prettier": "3.5.2", "tsx": "^4.7.0", "typescript": "^5.3.0" diff --git a/examples/typescript/pnpm-lock.yaml b/examples/typescript/pnpm-lock.yaml index aab67f046d..6c0820b206 100644 --- a/examples/typescript/pnpm-lock.yaml +++ b/examples/typescript/pnpm-lock.yaml @@ -521,16 +521,16 @@ importers: version: 0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) '@coinbase/agentkit-langchain': specifier: ^0.3.0 - version: 0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + version: 0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) '@langchain/core': specifier: ^0.3.43 - version: 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + version: 0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) '@langchain/langgraph': specifier: ^0.2.62 - version: 0.2.74(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76)) + version: 0.2.74(@langchain/core@0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76)) '@langchain/openai': specifier: ^0.5.2 - version: 0.5.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 0.5.18(@langchain/core@0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) dotenv: specifier: ^16.4.7 version: 16.6.1 @@ -689,7 +689,7 @@ importers: version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: file:../../../../typescript/packages/x402 - version: file:../../typescript/packages/x402(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: file:../../typescript/packages/x402(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2))(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) x402-axios: specifier: workspace:* version: link:../../../../typescript/packages/x402-axios @@ -875,6 +875,9 @@ importers: '@eslint/js': specifier: ^9.24.0 version: 9.33.0 + '@types/express': + specifier: ^5.0.3 + version: 5.0.3 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2) @@ -959,7 +962,7 @@ importers: dependencies: '@coinbase/onchainkit': specifier: latest - version: 0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + version: 1.1.1(@tanstack/query-core@5.85.5)(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76) '@coinbase/x402': specifier: workspace:* version: link:../../../../typescript/packages/coinbase-x402 @@ -1190,7 +1193,7 @@ importers: dependencies: '@coinbase/onchainkit': specifier: latest - version: 0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 1.1.1(@tanstack/query-core@5.85.5)(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76) '@tanstack/react-query': specifier: ^5 version: 5.85.5(react@19.1.1) @@ -1208,7 +1211,7 @@ importers: version: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: specifier: ^2.15.6 - version: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + version: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) x402: specifier: workspace:* version: link:../../../../typescript/packages/x402 @@ -2223,6 +2226,14 @@ packages: react: ^18 || ^19 react-dom: ^18 || ^19 + '@coinbase/onchainkit@1.1.1': + resolution: {integrity: sha512-kQW852v5/SW0EXo2MY9uQCXrQLWmOOLObSUwAxsOLwL72GYfeg+GUzVKguydSwUEa08thBvdKFB/JvX4OA48Og==} + peerDependencies: + react: ^19 + react-dom: ^19 + viem: ^2.27 + wagmi: ^2.16 + '@coinbase/wallet-sdk@3.9.3': resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} @@ -2738,12 +2749,27 @@ packages: '@floating-ui/dom@1.7.3': resolution: {integrity: sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==} + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + '@floating-ui/react-dom@2.1.5': resolution: {integrity: sha512-HDO/1/1oH9fjj4eLgegrlH3dklZpHtUYYFiVwMUwfGvk9jWDRWqkklA2/NFScknrcNSspbV868WjXORvreDX+Q==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' + '@floating-ui/react-dom@2.1.6': + resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/react@0.27.16': + resolution: {integrity: sha512-9O8N4SeG2z++TSM8QA/KTeKFBVCNEz/AGS7gWPJf6KFRzmRWixFRnCnkPHRDwSVZW6QPDO6uT0P2SpWNKCc9/g==} + peerDependencies: + react: '>=17.0.0' + react-dom: '>=17.0.0' + '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} @@ -8884,9 +8910,15 @@ packages: resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} engines: {node: ^14.18.0 || >=16.0.0} + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + tailwind-merge@2.6.0: resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} + tailwind-merge@3.3.1: + resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} + tailwindcss@3.4.17: resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} engines: {node: '>=14.0.0'} @@ -9353,6 +9385,12 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + usehooks-ts@3.1.1: + resolution: {integrity: sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA==} + engines: {node: '>=16.15.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc + utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} engines: {node: '>=6.14.2'} @@ -10714,10 +10752,10 @@ snapshots: '@cfworker/json-schema@4.1.1': {} - '@coinbase/agentkit-langchain@0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': + '@coinbase/agentkit-langchain@0.3.0(@coinbase/agentkit@0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10))(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': dependencies: '@coinbase/agentkit': 0.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) zod: 3.25.76 transitivePeerDependencies: - '@opentelemetry/api' @@ -10903,10 +10941,16 @@ snapshots: - utf-8-validate - zod - '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@coinbase/onchainkit@1.1.1(@tanstack/query-core@5.85.5)(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)': dependencies: - '@farcaster/frame-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@floating-ui/react': 0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@tanstack/react-query': 5.85.5(react@19.1.1) '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) clsx: 2.1.1 @@ -10915,36 +10959,52 @@ snapshots: qrcode: 1.5.4 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - tailwind-merge: 2.6.0 + tailwind-merge: 3.3.1 + usehooks-ts: 3.1.1(react@19.1.1) viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + wagmi: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@farcaster/miniapp-sdk' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - '@tanstack/query-core' - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch + - '@types/react-dom' + - bufferutil + - encoding + - immer + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@coinbase/onchainkit@1.1.1(@tanstack/query-core@5.85.5)(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)': + dependencies: + '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-wagmi-connector': 1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@floating-ui/react': 0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@tanstack/react-query': 5.85.5(react@19.1.1) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + clsx: 2.1.1 + graphql: 16.11.0 + graphql-request: 6.1.0(encoding@0.1.13)(graphql@16.11.0) + qrcode: 1.5.4 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + tailwind-merge: 3.3.1 + usehooks-ts: 3.1.1(react@19.1.1) + viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + transitivePeerDependencies: + - '@tanstack/query-core' + - '@types/react' + - '@types/react-dom' - bufferutil - - db0 - encoding - immer - - ioredis - - supports-color - typescript - - uploadthing - use-sync-external-store - utf-8-validate - zod @@ -11495,16 +11555,16 @@ snapshots: - utf-8-validate - zod - '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@farcaster/miniapp-wagmi-connector@1.0.0(@farcaster/miniapp-sdk@0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: '@farcaster/miniapp-sdk': 0.1.9(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@farcaster/quick-auth@0.0.5(typescript@5.9.2)': @@ -11528,12 +11588,37 @@ snapshots: '@floating-ui/core': 1.7.3 '@floating-ui/utils': 0.2.10 + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 + '@floating-ui/react-dom@2.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/dom': 1.7.3 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + '@floating-ui/react-dom@2.1.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/dom': 1.7.3 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + + '@floating-ui/react-dom@2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/dom': 1.7.4 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + + '@floating-ui/react@0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@floating-ui/utils': 0.2.10 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + tabbable: 6.2.0 + '@floating-ui/utils@0.2.10': {} '@gar/promisify@1.1.3': {} @@ -11708,14 +11793,14 @@ snapshots: '@jup-ag/api@6.0.44': {} - '@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': + '@langchain/core@0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': dependencies: '@cfworker/json-schema': 4.1.1 ansi-styles: 5.2.0 camelcase: 6.3.0 decamelize: 1.2.0 js-tiktoken: 1.0.21 - langsmith: 0.3.62(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + langsmith: 0.3.62(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) mustache: 4.2.0 p-queue: 6.6.2 p-retry: 4.6.2 @@ -11728,27 +11813,27 @@ snapshots: - '@opentelemetry/sdk-trace-base' - openai - '@langchain/langgraph-checkpoint@0.0.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': + '@langchain/langgraph-checkpoint@0.0.18(@langchain/core@0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': dependencies: - '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) uuid: 10.0.0 - '@langchain/langgraph-sdk@0.0.109(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@langchain/langgraph-sdk@0.0.109(@langchain/core@0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@types/json-schema': 7.0.15 p-queue: 6.6.2 p-retry: 4.6.2 uuid: 9.0.1 optionalDependencies: - '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - '@langchain/langgraph@0.2.74(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76))': + '@langchain/langgraph@0.2.74(@langchain/core@0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(zod-to-json-schema@3.24.6(zod@3.25.76))': dependencies: - '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) - '@langchain/langgraph-checkpoint': 0.0.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) - '@langchain/langgraph-sdk': 0.0.109(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@langchain/core': 0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/langgraph-checkpoint': 0.0.18(@langchain/core@0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) + '@langchain/langgraph-sdk': 0.0.109(@langchain/core@0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) uuid: 10.0.0 zod: 3.25.76 optionalDependencies: @@ -11757,11 +11842,11 @@ snapshots: - react - react-dom - '@langchain/openai@0.5.18(@langchain/core@0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@langchain/openai@0.5.18(@langchain/core@0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@langchain/core': 0.3.72(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/core': 0.3.72(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) js-tiktoken: 1.0.21 - openai: 5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + openai: 5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - ws @@ -11916,7 +12001,7 @@ snapshots: '@metamask/safe-event-emitter@3.1.2': {} - '@metamask/sdk-communication-layer@0.32.0(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metamask/sdk-communication-layer@0.32.0(cross-fetch@4.1.0)(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: bufferutil: 4.0.9 cross-fetch: 4.1.0(encoding@0.1.13) @@ -11940,7 +12025,7 @@ snapshots: '@babel/runtime': 7.28.3 '@metamask/onboarding': 1.0.1 '@metamask/providers': 16.1.0 - '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0)(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@metamask/sdk-install-modal-web': 0.32.0 '@paulmillr/qr': 0.2.1 bowser: 2.12.0 @@ -12249,6 +12334,15 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -12315,12 +12409,30 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.10)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-context-menu@2.2.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -12341,6 +12453,12 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-context@1.1.2(@types/react@19.1.10)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -12363,12 +12481,40 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@19.1.1) + aria-hidden: 1.2.6 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-direction@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-direction@1.1.1(@types/react@19.1.10)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -12382,6 +12528,19 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -12397,12 +12556,33 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.1.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.1.10)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) @@ -12414,6 +12594,17 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-form@0.1.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -12456,6 +12647,13 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-id@1.1.1(@types/react@19.1.10)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-label@2.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -12491,6 +12689,32 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-menu@2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) + aria-hidden: 1.2.6 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-menubar@1.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -12590,6 +12814,29 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@19.1.1) + aria-hidden: 1.2.6 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/react-dom': 2.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -12608,6 +12855,24 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/react-dom': 2.1.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/rect': 1.1.1 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -12618,6 +12883,16 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@18.3.1) @@ -12628,6 +12903,16 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@18.3.1) @@ -12637,6 +12922,15 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-progress@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@18.3.1) @@ -12682,6 +12976,23 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.1 @@ -12763,6 +13074,13 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-slot@1.2.3(@types/react@19.1.10)(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-switch@1.2.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -12794,6 +13112,22 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-toast@1.2.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -12814,6 +13148,26 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-toast@1.2.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -12881,6 +13235,12 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.10)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.10)(react@18.3.1)': dependencies: '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.10)(react@18.3.1) @@ -12889,6 +13249,14 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.10)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.10)(react@18.3.1)': dependencies: '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) @@ -12896,6 +13264,13 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.10)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@18.3.1) @@ -12903,10 +13278,17 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 - '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.1.10)(react@18.3.1)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.10)(react@19.1.1)': dependencies: - react: 18.3.1 - use-sync-external-store: 1.5.0(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + + '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.1.10)(react@18.3.1)': + dependencies: + react: 18.3.1 + use-sync-external-store: 1.5.0(react@18.3.1) optionalDependencies: '@types/react': 19.1.10 @@ -12916,6 +13298,12 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.10)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: react: 18.3.1 @@ -12929,6 +13317,13 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.10)(react@19.1.1)': + dependencies: + '@radix-ui/rect': 1.1.1 + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.10)(react@18.3.1)': dependencies: '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@18.3.1) @@ -12936,6 +13331,13 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.10)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.10 + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -12945,6 +13347,15 @@ snapshots: '@types/react': 19.1.10 '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) + '@radix-ui/rect@1.1.1': {} '@radix-ui/themes@3.2.1(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -13015,45 +13426,11 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-controllers@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - 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/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - '@reown/appkit-controllers@1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) valtio: 1.13.2(react@19.1.1) viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: @@ -13118,41 +13495,6 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-pay@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) - lit: 3.3.0 - valtio: 1.13.2(@types/react@19.1.10)(react@19.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' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - '@reown/appkit-pay@1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -13228,42 +13570,6 @@ snapshots: - valtio - zod - '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - 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/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - valtio - - zod - '@reown/appkit-scaffold-ui@1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(react@19.1.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -13334,40 +13640,6 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-ui@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - 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/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - '@reown/appkit-ui@1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -13439,43 +13711,6 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-utils@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - 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/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - '@reown/appkit-utils@1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(react@19.1.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -13483,7 +13718,7 @@ snapshots: '@reown/appkit-polyfills': 1.7.8 '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) valtio: 1.13.2(react@19.1.1) viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: @@ -13566,48 +13801,6 @@ snapshots: - utf-8-validate - zod - '@reown/appkit@1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-controllers': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-pay': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) - '@reown/appkit-ui': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@reown/appkit-utils': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.10)(react@19.1.1))(zod@3.25.76) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - bs58: 6.0.0 - valtio: 1.13.2(@types/react@19.1.10)(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - 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/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - '@reown/appkit@1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -13619,7 +13812,7 @@ snapshots: '@reown/appkit-utils': 1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(valtio@1.13.2(react@19.1.1))(zod@3.25.76) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10) '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) bs58: 6.0.0 valtio: 1.13.2(react@19.1.1) viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -13806,27 +13999,27 @@ snapshots: dependencies: '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(typescript@5.9.2))': + '@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: - '@solana/kit': 2.3.0(typescript@5.9.2) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(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.9.2)(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.9.2))': dependencies: '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(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.9.2) - '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(typescript@5.9.2))(@solana/sysvars@2.3.0(typescript@5.9.2))': + '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2))': dependencies: - '@solana/kit': 2.3.0(typescript@5.9.2) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(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.9.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/token@0.5.1(@solana/kit@2.3.0(typescript@5.9.2))': + '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: - '@solana/kit': 2.3.0(typescript@5.9.2) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/accounts@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': dependencies: @@ -14033,31 +14226,6 @@ snapshots: - fastestsmallesttextencoderdecoder - ws - '@solana/kit@2.3.0(typescript@5.9.2)': - dependencies: - '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/functional': 2.3.0(typescript@5.9.2) - '@solana/instructions': 2.3.0(typescript@5.9.2) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/programs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-parsed-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-spec-types': 2.3.0(typescript@5.9.2) - '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/signers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transaction-confirmation': 2.3.0(typescript@5.9.2) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/nominal-types@2.3.0(typescript@5.9.2)': dependencies: typescript: 5.9.2 @@ -14373,23 +14541,6 @@ snapshots: - fastestsmallesttextencoderdecoder - ws - '@solana/transaction-confirmation@2.3.0(typescript@5.9.2)': - dependencies: - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/errors': 2.3.0(typescript@5.9.2) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/promises': 2.3.0(typescript@5.9.2) - '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) - typescript: 5.9.2 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/transaction-messages@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': dependencies: '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) @@ -15025,7 +15176,7 @@ snapshots: loupe: 3.2.0 tinyrainbow: 2.0.0 - '@wagmi/connectors@5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': + '@wagmi/connectors@5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': dependencies: '@base-org/account': 1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) @@ -15033,7 +15184,7 @@ snapshots: '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -15111,49 +15262,6 @@ snapshots: - utf-8-validate - zod - '@wagmi/connectors@5.9.4(@types/react@19.1.10)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': - dependencies: - '@base-org/account': 1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) - '@gemini-wallet/core': 0.2.0(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - optionalDependencies: - typescript: 5.9.2 - 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/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - immer - - ioredis - - react - - supports-color - - uploadthing - - use-sync-external-store - - utf-8-validate - - zod - '@wagmi/connectors@5.9.4(@wagmi/core@2.19.0(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': dependencies: '@base-org/account': 1.1.1(@types/react@19.1.10)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) @@ -15357,46 +15465,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/ethereum-provider@2.21.1(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - dependencies: - '@reown/appkit': 1.7.8(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) - '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - 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/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/ethereum-provider@2.21.1(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit': 1.7.8(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -15407,7 +15475,7 @@ snapshots: '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) - '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: @@ -15698,45 +15766,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - dependencies: - '@walletconnect/events': 1.0.1 - '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) - '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.0(@upstash/redis@1.35.3) - '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - es-toolkit: 1.33.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/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/universal-provider@2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/events': 1.0.1 @@ -15776,45 +15805,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': - dependencies: - '@walletconnect/events': 1.0.1 - '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.3) - '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - '@walletconnect/types': 2.21.1(@upstash/redis@1.35.3) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - es-toolkit: 1.33.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/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/utils@2.21.0(@upstash/redis@1.35.3)(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/ciphers': 1.2.1 @@ -17323,7 +17313,7 @@ snapshots: '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.5(eslint@8.57.1) @@ -17352,44 +17342,44 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.1 - eslint: 8.57.1 + eslint: 9.33.0(jiti@1.21.7) get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 tinyglobby: 0.2.14 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.33.0(jiti@1.21.7)))(eslint@9.33.0(jiti@1.21.7)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.1 - eslint: 9.33.0(jiti@1.21.7) + eslint: 8.57.1 get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 tinyglobby: 0.2.14 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.33.0(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -17415,7 +17405,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -18748,7 +18738,7 @@ snapshots: kuler@2.0.0: {} - langsmith@0.3.62(openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): + langsmith@0.3.62(openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): dependencies: '@types/uuid': 10.0.0 chalk: 4.1.2 @@ -18758,7 +18748,7 @@ snapshots: semver: 7.7.2 uuid: 10.0.0 optionalDependencies: - openai: 5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + openai: 5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) language-subtag-registry@0.3.23: {} @@ -19253,9 +19243,9 @@ snapshots: transitivePeerDependencies: - encoding - openai@5.13.1(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): + openai@5.13.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): optionalDependencies: - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) zod: 3.25.76 opensea-js@7.2.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): @@ -19805,6 +19795,14 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + react-remove-scroll-bar@2.3.8(@types/react@19.1.10)(react@19.1.1): + dependencies: + react: 19.1.1 + react-style-singleton: 2.2.3(@types/react@19.1.10)(react@19.1.1) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.10 + react-remove-scroll@2.7.1(@types/react@19.1.10)(react@18.3.1): dependencies: react: 18.3.1 @@ -19816,6 +19814,17 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + react-remove-scroll@2.7.1(@types/react@19.1.10)(react@19.1.1): + dependencies: + react: 19.1.1 + react-remove-scroll-bar: 2.3.8(@types/react@19.1.10)(react@19.1.1) + react-style-singleton: 2.2.3(@types/react@19.1.10)(react@19.1.1) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.1.10)(react@19.1.1) + use-sidecar: 1.1.3(@types/react@19.1.10)(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.10 + react-style-singleton@2.2.3(@types/react@19.1.10)(react@18.3.1): dependencies: get-nonce: 1.0.1 @@ -19824,6 +19833,14 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + react-style-singleton@2.2.3(@types/react@19.1.10)(react@19.1.1): + dependencies: + get-nonce: 1.0.1 + react: 19.1.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.10 + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -20550,8 +20567,12 @@ snapshots: dependencies: '@pkgr/core': 0.2.9 + tabbable@6.2.0: {} + tailwind-merge@2.6.0: {} + tailwind-merge@3.3.1: {} + tailwindcss@3.4.17: dependencies: '@alloc/quick-lru': 5.2.0 @@ -20977,6 +20998,13 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + use-callback-ref@1.3.3(@types/react@19.1.10)(react@19.1.1): + dependencies: + react: 19.1.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.10 + use-sidecar@1.1.3(@types/react@19.1.10)(react@18.3.1): dependencies: detect-node-es: 1.1.0 @@ -20985,6 +21013,14 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + use-sidecar@1.1.3(@types/react@19.1.10)(react@19.1.1): + dependencies: + detect-node-es: 1.1.0 + react: 19.1.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.10 + use-sync-external-store@1.2.0(react@19.1.1): dependencies: react: 19.1.1 @@ -21002,6 +21038,11 @@ snapshots: react: 19.1.1 optional: true + usehooks-ts@3.1.1(react@19.1.1): + dependencies: + lodash.debounce: 4.0.8 + react: 19.1.1 + utf-8-validate@5.0.10: dependencies: node-gyp-build: 4.8.4 @@ -21223,45 +21264,7 @@ snapshots: wagmi@2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(@upstash/redis@1.35.3)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): dependencies: '@tanstack/react-query': 5.85.5(react@19.1.1) - '@wagmi/connectors': 5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) - '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) - react: 19.1.1 - use-sync-external-store: 1.4.0(react@19.1.1) - viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) - optionalDependencies: - typescript: 5.9.2 - 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' - - '@tanstack/query-core' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - immer - - ioredis - - supports-color - - uploadthing - - utf-8-validate - - zod - - wagmi@2.16.4(@tanstack/query-core@5.85.5)(@tanstack/react-query@5.85.5(react@19.1.1))(@types/react@19.1.10)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): - dependencies: - '@tanstack/react-query': 5.85.5(react@19.1.1) - '@wagmi/connectors': 5.9.4(@types/react@19.1.10)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + '@wagmi/connectors': 5.9.4(@types/react@19.1.10)(@upstash/redis@1.35.3)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.5)(@types/react@19.1.10)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) @@ -21634,14 +21637,14 @@ snapshots: - uploadthing - utf-8-validate - x402@file:../../typescript/packages/x402(@solana/sysvars@2.3.0(typescript@5.9.2))(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10): + x402@file:../../typescript/packages/x402(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2))(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(ws@8.18.3(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(typescript@5.9.2)) - '@solana-program/token': 0.5.1(@solana/kit@2.3.0(typescript@5.9.2)) - '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(typescript@5.9.2))(@solana/sysvars@2.3.0(typescript@5.9.2)) - '@solana/kit': 2.3.0(typescript@5.9.2) - '@solana/transaction-confirmation': 2.3.0(typescript@5.9.2) + '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(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.9.2)(ws@8.18.3(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.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) viem: 2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: 2.16.4(@tanstack/react-query@5.85.5(react@19.1.1))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(viem@2.34.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) zod: 3.25.76 diff --git a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md index b1d0a26aec..7c61f1ded8 100644 --- a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md +++ b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md @@ -40,41 +40,81 @@ Returns the most suitable voucher for aggregation between a buyer-seller pair. ### POST /vouchers -Stores a new signed voucher in the facilitator's voucher store. +Stores a new signed voucher in the facilitator's voucher store after verifying it. The verification should be exactly the same as you'd get by POSTing to /verify. This allows for replacing that call for one to this endpoint. **Request Body:** ```json { - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "6000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1740673100, - "nonce": 3, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1740759400 + "paymentPayload": { + "x402Version": 1, + "network": "base-sepolia", + "scheme": "deferred", + "payload": { + "signature": "0x4b3f8e...", + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "6000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1740673100, + "nonce": 3, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1740759400 + } + } }, - "signature": "0x4b3f8e..." + "paymentRequirements": { + "x402Version": 1, + "network": "base-sepolia", + "scheme": "deferred", + "recipient": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "amount": "1000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "extra": { + "type": "aggregation", + "signature": "0x3a2f7e3b...", + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "5000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1740673000, + "nonce": 2, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1740759400 + } + } + } } ``` **Response (201 Created):** ```json { - "success": true, - "voucherId": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "nonce": 3 + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "6000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1740673100, + "nonce": 3, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1740759400, + "signature": "0x4b3f8e..." } ``` **Response (400 Bad Request):** ```json { - "success": false, - "error": "Voucher already exists" + "isValid": false, + "invalidReason": "invalid_deferred_evm_payload_signature", + "payer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C" } ``` diff --git a/typescript/packages/x402-express/src/index.ts b/typescript/packages/x402-express/src/index.ts index d00cf43f78..7cfd35a42d 100644 --- a/typescript/packages/x402-express/src/index.ts +++ b/typescript/packages/x402-express/src/index.ts @@ -441,6 +441,9 @@ export function deferredPaymentMiddleware( getAvailableVoucher: async (buyer: string, seller: string) => { const result = await deferredFacilitator.getAvailableVoucher(buyer, seller); if ("error" in result) { + if (result.error === "voucher_not_found") { + return null; + } throw new Error(result.error); } return result; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/index.ts b/typescript/packages/x402/src/schemes/deferred/evm/index.ts index e5f1e203a1..fa845ee266 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/index.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/index.ts @@ -4,5 +4,6 @@ export * from "./id"; export * from "./server"; export * from "./sign"; export * from "./store"; +export * from "./store.mock"; export * from "./utils/paymentUtils"; export * from "./verify"; From 678008705db6c22c7f6dbab01b37a9f9fb1905c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 2 Oct 2025 15:16:59 -0300 Subject: [PATCH 084/116] test: fix axios test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-axios/src/index.test.ts | 2 +- .../x402/src/schemes/deferred/evm/verify.test.ts | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/typescript/packages/x402-axios/src/index.test.ts b/typescript/packages/x402-axios/src/index.test.ts index 9cda6736a5..3d33963978 100644 --- a/typescript/packages/x402-axios/src/index.test.ts +++ b/typescript/packages/x402-axios/src/index.test.ts @@ -291,7 +291,7 @@ describe("withDeferredPaymentInterceptor", () => { // Set up the interceptor withDeferredPaymentInterceptor(mockAxiosClient, mockWalletClient); requestInterceptor = (mockAxiosClient.interceptors.request.use as ReturnType).mock - .calls[0][1]; + .calls[0][0]; responseInterceptor = (mockAxiosClient.interceptors.response.use as ReturnType) .mock.calls[0][1]; }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts index 3a6315e1c6..29e365d17e 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts @@ -20,9 +20,13 @@ import { VoucherStore } from "./store"; import { Account, Chain, getAddress, Transport } from "viem"; import { signVoucher } from "./sign"; -vi.mock("../../../shared", () => ({ - getNetworkId: vi.fn(), -})); +vi.mock("../../../shared", async (original: () => Promise>) => { + const actual = await original(); + return { + ...(actual as Record), + getNetworkId: vi.fn(), + }; +}); const buyer = createSigner( "base-sepolia", From f16d638948be47a8085d9e1626838579ccf1baa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 2 Oct 2025 15:28:16 -0300 Subject: [PATCH 085/116] test: add tests for deferred middleware in x402-express package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../packages/x402-express/src/index.test.ts | 374 +++++++++++++++++- 1 file changed, 371 insertions(+), 3 deletions(-) diff --git a/typescript/packages/x402-express/src/index.test.ts b/typescript/packages/x402-express/src/index.test.ts index fbd0b6195a..0e2288b642 100644 --- a/typescript/packages/x402-express/src/index.test.ts +++ b/typescript/packages/x402-express/src/index.test.ts @@ -1,16 +1,17 @@ import { NextFunction, Request, Response } from "express"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { getPaywallHtml, findMatchingRoute } from "x402/shared"; -import { exact } from "x402/schemes"; +import { exact, deferred } from "x402/schemes"; import { PaymentMiddlewareConfig, PaymentPayload, RoutesConfig, FacilitatorConfig, RouteConfig, + DeferredEvmPayloadSchema, } from "x402/types"; import { useFacilitator } from "x402/verify"; -import { paymentMiddleware } from "./index"; +import { paymentMiddleware, deferredPaymentMiddleware } from "./index"; import { Address as SolanaAddress } from "@solana/kit"; // Mock dependencies @@ -20,6 +21,10 @@ vi.mock("x402/verify", () => ({ settle: vi.fn(), supported: vi.fn(), list: vi.fn(), + deferred: { + getAvailableVoucher: vi.fn(), + storeVoucher: vi.fn(), + }, }), })); @@ -80,7 +85,7 @@ vi.mock("x402/shared/evm", () => ({ getUsdcAddressForChain: vi.fn().mockReturnValue("0x036CbD53842c5426634e7929541eC2318f3dCF7e"), })); -// Mock exact.evm.decodePayment +// Mock exact.evm.decodePayment and deferred.evm vi.mock("x402/schemes", () => ({ exact: { evm: { @@ -88,6 +93,14 @@ vi.mock("x402/schemes", () => ({ decodePayment: vi.fn(), }, }, + deferred: { + evm: { + encodePayment: vi.fn(), + decodePayment: vi.fn(), + getPaymentRequirementsExtra: vi.fn(), + VoucherStore: vi.fn(), + }, + }, })); describe("paymentMiddleware()", () => { @@ -703,3 +716,358 @@ describe("paymentMiddleware()", () => { }); }); }); + +describe("deferredPaymentMiddleware()", () => { + let mockReq: Partial; + let mockRes: Partial; + let mockNext: NextFunction; + let middleware: ReturnType; + let mockVerify: ReturnType["verify"]; + let mockDeferredFacilitator: ReturnType["deferred"]; + + const middlewareConfig: PaymentMiddlewareConfig = { + description: "Test deferred payment", + mimeType: "application/json", + maxTimeoutSeconds: 300, + outputSchema: { type: "object" }, + resource: "https://api.example.com/resource", + }; + + const facilitatorConfig: FacilitatorConfig = { + url: "https://facilitator.example.com", + }; + + const payTo = "0x1234567890123456789012345678901234567890"; + const escrow = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"; + + const routesConfig: RoutesConfig = { + "/test": { + price: "$0.001", + network: "base-sepolia", + config: middlewareConfig, + }, + }; + + const validVoucher = { + buyer: "0x1234567890123456789012345678901234567890", + seller: "0x1234567890123456789012345678901234567890", + valueAggregate: "1000", + nonce: 0, + id: "0x1234567890123456789012345678901234567890123456789012345678901234", + asset: "0x1234567890123456789012345678901234567890", + timestamp: 1715769600, + escrow: "0x1234567890123456789012345678901234567890", + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: "0xsignature", + }; + const validDeferredPayment: PaymentPayload = { + scheme: "deferred", + x402Version: 1, + network: "base-sepolia", + payload: { + voucher: validVoucher, + signature: "0xsignature", + }, + }; + const encodedValidDeferredPayment = "encoded-deferred-payment"; + + beforeEach(() => { + vi.resetAllMocks(); + mockReq = { + path: "/test", + method: "GET", + protocol: "https", + headers: { host: "api.example.com" }, + header: function (name: string) { + return this.headers[name.toLowerCase()]; + }, + } as Request; + mockRes = { + status: vi.fn().mockReturnThis(), + json: vi.fn().mockReturnThis(), + send: vi.fn().mockReturnThis(), + setHeader: vi.fn().mockReturnThis(), + end: vi.fn().mockReturnThis(), + headersSent: false, + } as unknown as Response; + mockNext = vi.fn(); + mockVerify = vi.fn(); + mockDeferredFacilitator = { + getAvailableVoucher: vi.fn(), + storeVoucher: vi.fn(), + }; + + vi.mocked(useFacilitator).mockReturnValue({ + verify: mockVerify, + settle: vi.fn(), + supported: vi.fn(), + list: vi.fn(), + deferred: mockDeferredFacilitator, + }); + + // Setup route pattern matching mock + vi.mocked(findMatchingRoute).mockImplementation((routePatterns, path, method) => { + if (path === "/test" && method === "GET") { + return { + pattern: /^\/test$/, + verb: "GET", + config: { + price: "$0.001", + network: "base-sepolia", + config: middlewareConfig, + }, + }; + } + return undefined; + }); + + // Setup deferred.evm mocks + vi.mocked(deferred.evm.encodePayment).mockReturnValue(encodedValidDeferredPayment); + vi.mocked(deferred.evm.decodePayment).mockReturnValue(validDeferredPayment); + vi.mocked(deferred.evm.getPaymentRequirementsExtra).mockResolvedValue({ + type: "new", + voucher: { + id: "0x1234567890123456789012345678901234567890123456789012345678901234", + escrow, + }, + }); + + // Mock DeferredEvmPayloadSchema.parse + vi.spyOn(DeferredEvmPayloadSchema, "parse").mockReturnValue({ + voucher: validVoucher, + signature: "0xsignature", + }); + }); + + it("should return 402 with payment requirements when no payment header is present", async () => { + middleware = deferredPaymentMiddleware(payTo, routesConfig, escrow, facilitatorConfig); + mockReq.headers = { host: "api.example.com" }; + + await middleware(mockReq as Request, mockRes as Response, mockNext); + + expect(mockRes.status).toHaveBeenCalledWith(402); + expect(mockRes.json).toHaveBeenCalledWith( + expect.objectContaining({ + error: "X-PAYMENT header is required", + accepts: expect.any(Array), + x402Version: 1, + }), + ); + }); + + it("should return 402 if payment decoding fails", async () => { + middleware = deferredPaymentMiddleware(payTo, routesConfig, escrow, facilitatorConfig); + mockReq.headers = { + "x-payment": "invalid-payment-header", + host: "api.example.com", + }; + (deferred.evm.decodePayment as ReturnType).mockImplementation(() => { + throw new Error("Invalid payment"); + }); + + await middleware(mockReq as Request, mockRes as Response, mockNext); + + expect(mockRes.status).toHaveBeenCalledWith(402); + expect(mockRes.json).toHaveBeenCalledWith( + expect.objectContaining({ + x402Version: 1, + error: expect.anything(), + accepts: expect.any(Array), + }), + ); + }); + + describe("with facilitator voucher store", () => { + beforeEach(() => { + middleware = deferredPaymentMiddleware(payTo, routesConfig, escrow, facilitatorConfig); + }); + + it("should store voucher via facilitator and proceed if valid", async () => { + mockReq.headers = { + "x-payment": encodedValidDeferredPayment, + host: "api.example.com", + }; + (mockDeferredFacilitator.storeVoucher as ReturnType).mockResolvedValue( + undefined, + ); + + await middleware(mockReq as Request, mockRes as Response, mockNext); + + expect(deferred.evm.decodePayment).toHaveBeenCalledWith(encodedValidDeferredPayment); + expect(mockDeferredFacilitator.storeVoucher).toHaveBeenCalledWith( + validDeferredPayment, + expect.any(Object), + ); + expect(mockVerify).not.toHaveBeenCalled(); // Skip verify when using facilitator store + expect(mockNext).toHaveBeenCalled(); + }); + + it("should return 402 if facilitator voucher storage fails", async () => { + mockReq.headers = { + "x-payment": encodedValidDeferredPayment, + host: "api.example.com", + }; + (mockDeferredFacilitator.storeVoucher as ReturnType).mockRejectedValue( + new Error("Storage failed"), + ); + + await middleware(mockReq as Request, mockRes as Response, mockNext); + + expect(mockRes.status).toHaveBeenCalledWith(402); + expect(mockRes.json).toHaveBeenCalledWith( + expect.objectContaining({ + x402Version: 1, + error: expect.any(Error), + accepts: expect.any(Array), + }), + ); + }); + + it("should set X-PAYMENT-RESPONSE header on successful payment", async () => { + mockReq.headers = { + "x-payment": encodedValidDeferredPayment, + host: "api.example.com", + }; + (mockDeferredFacilitator.storeVoucher as ReturnType).mockResolvedValue( + undefined, + ); + + await middleware(mockReq as Request, mockRes as Response, mockNext); + + expect(mockRes.setHeader).toHaveBeenCalledWith("X-PAYMENT-RESPONSE", expect.any(String)); + expect(mockNext).toHaveBeenCalled(); + }); + + it("should not set X-PAYMENT-RESPONSE if protected route returns status >= 400", async () => { + mockReq.headers = { + "x-payment": encodedValidDeferredPayment, + host: "api.example.com", + }; + (mockDeferredFacilitator.storeVoucher as ReturnType).mockResolvedValue( + undefined, + ); + + // Simulate downstream handler setting status 500 + (mockRes.status as ReturnType).mockImplementation(function ( + this: Response, + code: number, + ) { + this.statusCode = code; + return this; + }); + mockRes.statusCode = 500; + + await middleware(mockReq as Request, mockRes as Response, mockNext); + + expect(mockRes.setHeader).not.toHaveBeenCalledWith("X-PAYMENT-RESPONSE", expect.any(String)); + expect(mockRes.statusCode).toBe(500); + }); + }); + + describe("with custom voucher store", () => { + let mockVoucherStore: { + getAvailableVoucher: ReturnType; + storeVoucher: ReturnType; + }; + + beforeEach(() => { + mockVoucherStore = { + getAvailableVoucher: vi.fn().mockResolvedValue(null), + storeVoucher: vi.fn().mockResolvedValue(undefined), + }; + middleware = deferredPaymentMiddleware( + payTo, + routesConfig, + escrow, + facilitatorConfig, + mockVoucherStore, + ); + }); + + it("should verify payment and store voucher locally when using custom store", async () => { + mockReq.headers = { + "x-payment": encodedValidDeferredPayment, + host: "api.example.com", + }; + (mockVerify as ReturnType).mockResolvedValue({ isValid: true }); + + await middleware(mockReq as Request, mockRes as Response, mockNext); + + expect(deferred.evm.decodePayment).toHaveBeenCalledWith(encodedValidDeferredPayment); + expect(mockVerify).toHaveBeenCalledWith(validDeferredPayment, expect.any(Object)); + expect(mockVoucherStore.storeVoucher).toHaveBeenCalledWith( + expect.objectContaining({ + signature: "0xsignature", + }), + ); + expect(mockDeferredFacilitator.storeVoucher).not.toHaveBeenCalled(); + expect(mockNext).toHaveBeenCalled(); + }); + + it("should return 402 if payment verification fails with custom store", async () => { + mockReq.headers = { + "x-payment": encodedValidDeferredPayment, + host: "api.example.com", + }; + (mockVerify as ReturnType).mockResolvedValue({ + isValid: false, + invalidReason: "insufficient_funds", + payer: "0x123", + }); + + await middleware(mockReq as Request, mockRes as Response, mockNext); + + expect(mockRes.status).toHaveBeenCalledWith(402); + expect(mockRes.json).toHaveBeenCalledWith( + expect.objectContaining({ + x402Version: 1, + error: "insufficient_funds", + accepts: expect.any(Array), + payer: "0x123", + }), + ); + expect(mockVoucherStore.storeVoucher).not.toHaveBeenCalled(); + }); + + it("should return 402 if verification throws error with custom store", async () => { + mockReq.headers = { + "x-payment": encodedValidDeferredPayment, + host: "api.example.com", + }; + (mockVerify as ReturnType).mockRejectedValue(new Error("Verification failed")); + + await middleware(mockReq as Request, mockRes as Response, mockNext); + + expect(mockRes.status).toHaveBeenCalledWith(402); + expect(mockRes.json).toHaveBeenCalledWith( + expect.objectContaining({ + x402Version: 1, + error: expect.any(Error), + accepts: expect.any(Array), + }), + ); + expect(mockVoucherStore.storeVoucher).not.toHaveBeenCalled(); + }); + + it("should return 402 if local voucher storage fails", async () => { + mockReq.headers = { + "x-payment": encodedValidDeferredPayment, + host: "api.example.com", + }; + (mockVerify as ReturnType).mockResolvedValue({ isValid: true }); + mockVoucherStore.storeVoucher.mockRejectedValue(new Error("Storage failed")); + + await middleware(mockReq as Request, mockRes as Response, mockNext); + + expect(mockRes.status).toHaveBeenCalledWith(402); + expect(mockRes.json).toHaveBeenCalledWith( + expect.objectContaining({ + x402Version: 1, + error: expect.any(Error), + accepts: expect.any(Array), + }), + ); + }); + }); +}); From b7c2848d9ee64f5ed8ff52b2e066f7c93586cbd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 2 Oct 2025 17:42:20 -0300 Subject: [PATCH 086/116] feat(deferred): add support to x402 package for deposit with auth flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/DeferredPaymentEscrow.sol | 30 + .../src/libraries/EscrowSignatureLib.sol | 5 +- .../test/ThawWithdrawTest.t.sol | 36 +- .../test/ViewFunctionTest.t.sol | 4 +- .../test/VoucherCollectionTest.t.sol | 15 +- .../src/schemes/deferred/evm/facilitator.ts | 21 +- .../x402/src/schemes/deferred/evm/sign.ts | 196 ++- .../x402/src/schemes/deferred/evm/verify.ts | 171 +- .../src/types/shared/evm/deferredEscrowABI.ts | 1497 ++++------------- .../x402/src/types/shared/evm/typedData.ts | 17 + .../x402/src/types/verify/constants.ts | 1 + .../x402/src/types/verify/schemes/deferred.ts | 67 + 12 files changed, 848 insertions(+), 1212 deletions(-) diff --git a/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol b/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol index 47dc1fb078..505087913b 100644 --- a/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol +++ b/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol @@ -455,6 +455,36 @@ contract DeferredPaymentEscrow is ReentrancyGuard, EIP712, IDeferredPaymentEscro return EscrowSignatureLib.isFlushAllAuthorizationValid(auth, signature, _domainSeparatorV4()); } + /** + * @notice Validate a deposit authorization nonce + * @param buyer Address of the buyer + * @param nonce The nonce to validate + * @return True if nonce is used + */ + function isDepositAuthorizationNonceUsed(address buyer, bytes32 nonce) external view returns (bool) { + return _getMainStorage().usedDepositNonces[buyer][nonce]; + } + + /** + * @notice Validate a flush authorization nonce + * @param buyer Address of the buyer + * @param nonce The nonce to validate + * @return True if nonce is used + */ + function isFlushAuthorizationNonceUsed(address buyer, bytes32 nonce) external view returns (bool) { + return _getMainStorage().usedFlushNonces[buyer][nonce]; + } + + /** + * @notice Validate a flush all authorization nonce + * @param buyer Address of the buyer + * @param nonce The nonce to validate + * @return True if nonce is used + */ + function isFlushAllAuthorizationNonceUsed(address buyer, bytes32 nonce) external view returns (bool) { + return _getMainStorage().usedFlushAllNonces[buyer][nonce]; + } + /** * @notice Get the EIP-712 domain separator * @return Domain separator hash diff --git a/solidity/deferred-escrow/src/libraries/EscrowSignatureLib.sol b/solidity/deferred-escrow/src/libraries/EscrowSignatureLib.sol index 892a4bfdb0..c8d08a37b0 100644 --- a/solidity/deferred-escrow/src/libraries/EscrowSignatureLib.sol +++ b/solidity/deferred-escrow/src/libraries/EscrowSignatureLib.sol @@ -125,9 +125,8 @@ library EscrowSignatureLib { bytes calldata signature, bytes32 domainSeparator ) external view returns (bool) { - bytes32 structHash = keccak256( - abi.encode(FLUSH_ALL_AUTHORIZATION_TYPEHASH, auth.buyer, auth.nonce, auth.expiry) - ); + bytes32 structHash = + keccak256(abi.encode(FLUSH_ALL_AUTHORIZATION_TYPEHASH, auth.buyer, auth.nonce, auth.expiry)); bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); diff --git a/solidity/deferred-escrow/test/ThawWithdrawTest.t.sol b/solidity/deferred-escrow/test/ThawWithdrawTest.t.sol index 058ce3c7b0..1f7e9589c2 100644 --- a/solidity/deferred-escrow/test/ThawWithdrawTest.t.sol +++ b/solidity/deferred-escrow/test/ThawWithdrawTest.t.sol @@ -236,7 +236,11 @@ contract ThawWithdrawTest is BaseTest { // Create flush authorization IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ - buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + nonce: nonce, + expiry: expiry }); // Sign with buyer's private key using helper @@ -272,7 +276,11 @@ contract ThawWithdrawTest is BaseTest { // Create flush authorization IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ - buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + nonce: nonce, + expiry: expiry }); // Sign authorization @@ -297,7 +305,11 @@ contract ThawWithdrawTest is BaseTest { // Create flush authorization IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ - buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + nonce: nonce, + expiry: expiry }); // Sign with buyer's private key @@ -377,7 +389,11 @@ contract ThawWithdrawTest is BaseTest { // Create flush authorization with updated expiry IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ - buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + nonce: nonce, + expiry: expiry }); bytes memory signature = signFlushAuthorization(auth, buyerPrivateKey); @@ -456,7 +472,11 @@ contract ThawWithdrawTest is BaseTest { // Create flush authorization IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ - buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + nonce: nonce, + expiry: expiry }); // Sign with buyer's private key @@ -498,7 +518,11 @@ contract ThawWithdrawTest is BaseTest { // Create flush authorization IDeferredPaymentEscrow.FlushAuthorization memory auth = IDeferredPaymentEscrow.FlushAuthorization({ - buyer: buyerFromPrivateKey, seller: seller, asset: address(usdc), nonce: nonce, expiry: expiry + buyer: buyerFromPrivateKey, + seller: seller, + asset: address(usdc), + nonce: nonce, + expiry: expiry }); // Sign authorization diff --git a/solidity/deferred-escrow/test/ViewFunctionTest.t.sol b/solidity/deferred-escrow/test/ViewFunctionTest.t.sol index 2a0f2cfa79..943bd6b8a4 100644 --- a/solidity/deferred-escrow/test/ViewFunctionTest.t.sol +++ b/solidity/deferred-escrow/test/ViewFunctionTest.t.sol @@ -110,7 +110,9 @@ contract ViewFunctionTest is BaseTest { // Test flush all authorization validation IDeferredPaymentEscrow.FlushAllAuthorization memory flushAllAuth = IDeferredPaymentEscrow.FlushAllAuthorization({ - buyer: buyerFromPrivateKey, nonce: keccak256("flush-all-nonce"), expiry: voucherExpiry + buyer: buyerFromPrivateKey, + nonce: keccak256("flush-all-nonce"), + expiry: voucherExpiry }); bytes memory flushAllSignature = signFlushAllAuthorization(flushAllAuth, buyerPrivateKey); diff --git a/solidity/deferred-escrow/test/VoucherCollectionTest.t.sol b/solidity/deferred-escrow/test/VoucherCollectionTest.t.sol index 69c319c68d..f3f6a77052 100644 --- a/solidity/deferred-escrow/test/VoucherCollectionTest.t.sol +++ b/solidity/deferred-escrow/test/VoucherCollectionTest.t.sol @@ -200,12 +200,10 @@ contract VoucherCollectionTest is BaseTest { ); IDeferredPaymentEscrow.SignedVoucher[] memory signedVouchers = new IDeferredPaymentEscrow.SignedVoucher[](2); - signedVouchers[0] = IDeferredPaymentEscrow.SignedVoucher({ - voucher: voucher1, signature: signVoucher(voucher1, buyerPrivateKey) - }); - signedVouchers[1] = IDeferredPaymentEscrow.SignedVoucher({ - voucher: voucher2, signature: signVoucher(voucher2, buyerPrivateKey) - }); + signedVouchers[0] = + IDeferredPaymentEscrow.SignedVoucher({voucher: voucher1, signature: signVoucher(voucher1, buyerPrivateKey)}); + signedVouchers[1] = + IDeferredPaymentEscrow.SignedVoucher({voucher: voucher2, signature: signVoucher(voucher2, buyerPrivateKey)}); // First batch collection vm.prank(seller); @@ -301,9 +299,8 @@ contract VoucherCollectionTest is BaseTest { } function test_Collect_ZeroVoucherValue() public { - IDeferredPaymentEscrow.Voucher memory voucher = createVoucher( - VOUCHER_ID, buyerFromPrivateKey, seller, 0, address(usdc), voucherTimestamp, 1, voucherExpiry - ); + IDeferredPaymentEscrow.Voucher memory voucher = + createVoucher(VOUCHER_ID, buyerFromPrivateKey, seller, 0, address(usdc), voucherTimestamp, 1, voucherExpiry); bytes memory signature = signVoucher(voucher, buyerPrivateKey); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 3983194b6f..266a234bb1 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -8,6 +8,7 @@ import { VerifyResponse, } from "../../../types/verify"; import { + DeferredEscrowDepositAuthorization, DeferredEvmPayloadVoucher, DeferredPaymentPayloadSchema, DeferredPaymentRequirementsSchema, @@ -89,7 +90,11 @@ export async function verify< } // Verify the onchain state allows the payment to be settled - const onchainResult = await verifyOnchainState(client, paymentPayload.payload.voucher); + const onchainResult = await verifyOnchainState( + client, + paymentPayload.payload.voucher, + paymentPayload.payload.depositAuthorization, + ); if (!onchainResult.isValid) { return onchainResult; } @@ -136,8 +141,14 @@ export async function settle( }; } - const { voucher, signature } = paymentPayload.payload; - const response = await settleVoucher(wallet, voucher, signature, voucherStore); + const { voucher, signature, depositAuthorization } = paymentPayload.payload; + const response = await settleVoucher( + wallet, + voucher, + signature, + voucherStore, + depositAuthorization, + ); return { ...response, @@ -157,6 +168,7 @@ export async function settle( * @param voucher - The voucher to settle * @param signature - The signature of the voucher * @param voucherStore - The voucher store to use for verification + * @param depositAuthorization - A deposit authorization to use for verification purposes * @returns A PaymentExecutionResponse containing the transaction status and hash */ export async function settleVoucher( @@ -164,6 +176,7 @@ export async function settleVoucher { // Verify the voucher signature const signatureResult = await verifyVoucherSignature(voucher, signature); @@ -194,7 +207,7 @@ export async function settleVoucher( + walletClient: SignerWallet | LocalAccount, + permit: DeferredEscrowDepositAuthorizationPermit, + chainId: number, + asset: Address, +): Promise<{ signature: Hex }> { + const { domain, owner, spender, value, nonce, deadline } = permit; + const data = { + types: typedDataTypes, + primaryType: permitPrimaryType, + domain: { + name: domain.name, + version: domain.version, + chainId: chainId, + verifyingContract: getAddress(asset), + }, + message: { + owner: getAddress(owner), + spender: getAddress(spender), + value, + nonce, + deadline, + }, + }; + + if (isSignerWallet(walletClient)) { + const signature = await walletClient.signTypedData(data); + return { + signature, + }; + } else if (isAccount(walletClient) && walletClient.signTypedData) { + const signature = await walletClient.signTypedData(data); + return { + signature, + }; + } else { + throw new Error("Invalid wallet client provided does not support signTypedData"); + } +} + +/** + * Verifies a permit signature + * + * Note that the permit input object is not the actual EIP-712 signed message. It contains additional fields. + * + * @param permit - The permit to verify + * @param signature - The signature to verify + * @param signer - The address of the signer to verify + * @param chainId - The chain ID + * @param asset - The address of the asset + * @returns The address that signed the voucher + */ +export async function verifyPermit( + permit: DeferredEscrowDepositAuthorizationPermit, + signature: Hex, + signer: Address, + chainId: number, + asset: Address, +) { + const { domain, ...eip712Permit } = permit; + const permitTypedData = { + types: typedDataTypes, + primaryType: permitPrimaryType, + domain: { + name: domain.name, + version: domain.version, + chainId: chainId, + verifyingContract: getAddress(asset), + }, + message: eip712Permit, + }; + + const client = createConnectedClient(getNetworkName(chainId)); + return await client.verifyTypedData({ + address: signer, + ...permitTypedData, + signature: signature as Hex, + }); +} + +/** + * Signs a deferred escrow deposit authorization + * + * @param walletClient - The wallet client that will sign the authorization + * @param depositAuthorization - The deposit authorization to sign + * @param chainId - The chain ID + * @param escrow - The address of the escrow contract + * @returns The signature for the permit + */ +export async function signDepositAuthorizationInner< + transport extends Transport, + chain extends Chain, +>( + walletClient: SignerWallet | LocalAccount, + depositAuthorization: DeferredEscrowDepositAuthorizationInner, + chainId: number, + escrow: Address, +): Promise<{ signature: Hex }> { + const { buyer, seller, asset, amount, nonce, expiry } = depositAuthorization; + const data = { + types: typedDataTypes, + primaryType: depositAuthorizationPrimaryType, + domain: { + name: "DeferredPaymentEscrow", + version: "1", + chainId: chainId, + verifyingContract: getAddress(escrow), + }, + message: { + buyer: getAddress(buyer), + seller: getAddress(seller), + asset: getAddress(asset), + amount, + nonce, + expiry, + }, + }; + + if (isSignerWallet(walletClient)) { + const signature = await walletClient.signTypedData(data); + return { + signature, + }; + } else if (isAccount(walletClient) && walletClient.signTypedData) { + const signature = await walletClient.signTypedData(data); + return { + signature, + }; + } else { + throw new Error("Invalid wallet client provided does not support signTypedData"); + } +} + +/** + * Verifies a deposit authorization signature + * + * @param depositAuthorization - The deposit authorization to verify + * @param signature - The signature to verify + * @param signer - The address of the signer to verify + * @param chainId - The chain ID + * @param escrow - The address of the escrow contract + * @returns The address that signed the voucher + */ +export async function verifyDepositAuthorizationInner( + depositAuthorization: DeferredEscrowDepositAuthorizationInner, + signature: Hex, + signer: Address, + chainId: number, + escrow: Address, +) { + const depositAuthorizationTypedData = { + types: typedDataTypes, + primaryType: depositAuthorizationPrimaryType, + domain: { + name: "DeferredPaymentEscrow", + version: "1", + chainId: chainId, + verifyingContract: getAddress(escrow), + }, + message: { + buyer: getAddress(depositAuthorization.buyer), + seller: getAddress(depositAuthorization.seller), + asset: getAddress(depositAuthorization.asset), + amount: depositAuthorization.amount, + nonce: depositAuthorization.nonce, + expiry: depositAuthorization.expiry, + }, + }; + + const client = createConnectedClient(getNetworkName(chainId)); + return await client.verifyTypedData({ + address: signer, + ...depositAuthorizationTypedData, + signature: signature as Hex, + }); +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index f617ffd304..df0364ccc7 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -7,11 +7,12 @@ import { DeferredPaymentRequirements, DEFERRRED_SCHEME, } from "../../../types/verify/schemes/deferred"; -import { VerifyResponse } from "../../../types"; +import { DeferredEscrowDepositAuthorization, VerifyResponse } from "../../../types"; import { getNetworkId } from "../../../shared"; -import { verifyVoucher } from "./sign"; +import { verifyDepositAuthorizationInner, verifyPermit, verifyVoucher } from "./sign"; import { ConnectedClient } from "../../../types/shared/evm/wallet"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; +import { usdcABI } from "../../../types/shared/evm/erc20PermitABI"; import { VoucherStore } from "./store"; /** @@ -358,7 +359,8 @@ export function verifyVoucherDuplicate( } /** - * Verifies the onchain state allows the payment to be settled + * Verifies the onchain state allows the payment to be settled. Accepts an optional deposit authorization, treating + * the associated funds as additional balance in the escrow deposit. * * - ✅ (on-chain) Verifies the client is connected to the chain specified in the payment requirements * - ✅ (on-chain) Verifies buyer has sufficient asset balance @@ -366,6 +368,7 @@ export function verifyVoucherDuplicate( * * @param client - The client to use for the onchain state verification * @param voucher - The voucher to verify + * @param depositAuthorization - The deposit authorization to verify * @returns Verification result */ export async function verifyOnchainState< @@ -375,6 +378,7 @@ export async function verifyOnchainState< >( client: ConnectedClient, voucher: DeferredEvmPayloadVoucher, + depositAuthorization?: DeferredEscrowDepositAuthorization, ): Promise { // Verify the client is connected to the chain specified in the payment requirements if (client.chain.id !== voucher.chainId) { @@ -385,6 +389,21 @@ export async function verifyOnchainState< }; } + // If a deposit authorization is provided and valid we consider it as additional balance in the escrow deposit + let authorizationBalance = 0n; + if (depositAuthorization) { + // Verify the deposit authorization is valid for the voucher asset and chain id + const depositAuthorizationResult = await verifyDepositAuthorization( + client, + voucher, + depositAuthorization, + ); + if (!depositAuthorizationResult.isValid) { + return depositAuthorizationResult; + } + authorizationBalance = BigInt(depositAuthorization.depositAuthorization.amount); + } + // Verify buyer has sufficient asset balance in the escrow contract // buyer has to cover the outstanding amount let voucherOutstandingAmount: bigint; @@ -436,7 +455,7 @@ export async function verifyOnchainState< }; } - if (buyerAccount.balance < voucherOutstandingAmount) { + if (buyerAccount.balance + authorizationBalance < voucherOutstandingAmount) { return { isValid: false, invalidReason: "insufficient_funds", @@ -448,3 +467,147 @@ export async function verifyOnchainState< isValid: true, }; } + +/** + * Verifies a deposit authorization is valid. Checks the signature of the permit and the deposit authorization. + * + * @param client - The client to use for the onchain state verification + * @param voucher - The voucher that the deposit authorization is escrowing for + * @param depositAuthorization - The deposit authorization to verify + * @returns Verification result + */ +export async function verifyDepositAuthorization< + transport extends Transport, + chain extends Chain, + account extends Account | undefined, +>( + client: ConnectedClient, + voucher: DeferredEvmPayloadVoucher, + depositAuthorization: DeferredEscrowDepositAuthorization, +): Promise { + const { permit, depositAuthorization: depositAuthorizationInner } = depositAuthorization; + + // Verify the permit signature + const isPermitValid = await verifyPermit( + permit, + permit.signature as Hex, + permit.owner as Address, + voucher.chainId, + voucher.asset as Address, // This ensures the permit is for the voucher's asset + ); + if (!isPermitValid) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_permit_signature", + payer: permit.owner, + }; + } + + // Verify permit continuity + const now = Math.floor(Date.now() / 1000); + const oneWeek = 604800; + if ( + getAddress(permit.owner) !== getAddress(voucher.buyer) || + getAddress(permit.spender) !== getAddress(voucher.escrow) || + permit.deadline < now + oneWeek + ) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_permit_continuity", + payer: permit.owner, + }; + } + + // Verify deposit authorization signature + const isDepositAuthorizationValid = await verifyDepositAuthorizationInner( + depositAuthorizationInner, + depositAuthorizationInner.signature as Hex, + depositAuthorizationInner.buyer as Address, + voucher.chainId, + voucher.escrow as Address, + ); + if (!isDepositAuthorizationValid) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_signature", + payer: depositAuthorizationInner.buyer, + }; + } + + // Verify deposit authorization continuity + if ( + getAddress(depositAuthorizationInner.buyer) !== getAddress(voucher.buyer) || + getAddress(depositAuthorizationInner.seller) !== getAddress(voucher.seller) || + getAddress(depositAuthorizationInner.asset) !== getAddress(voucher.asset) || + depositAuthorizationInner.expiry < now + oneWeek + ) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_continuity", + payer: depositAuthorizationInner.buyer, + }; + } + + // Very permit / deposit authorization continuity + if ( + getAddress(depositAuthorizationInner.buyer) !== getAddress(permit.owner) || + BigInt(depositAuthorizationInner.amount) > BigInt(permit.value) + ) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_cross_continuity", + payer: depositAuthorizationInner.buyer, + }; + } + + // Verify permit nonce + try { + const permitNonce = await client.readContract({ + address: voucher.asset as Address, + abi: usdcABI, + functionName: "nonces", + args: [voucher.buyer as Address], + }); + if (permitNonce !== BigInt(permit.nonce)) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_permit_nonce_invalid", + payer: voucher.buyer, + }; + } + } catch { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_contract_call_failed_nonces", + payer: voucher.buyer, + }; + } + + // Verify deposit authorization nonce + try { + const nonceUsed = await client.readContract({ + address: voucher.escrow as Address, + abi: deferredEscrowABI, + functionName: "isDepositAuthorizationNonceUsed", + args: [voucher.buyer as Address, depositAuthorizationInner.nonce as Hex], + }); + if (nonceUsed) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_nonce_invalid", + payer: voucher.buyer, + }; + } + } catch { + return { + isValid: false, + invalidReason: + "invalid_deferred_evm_contract_call_failed_is_deposit_authorization_nonce_used", + payer: voucher.buyer, + }; + } + + return { + isValid: true, + }; +} diff --git a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts index d81b05e7ae..82223b9aca 100644 --- a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts +++ b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts @@ -1,88 +1,64 @@ export const deferredEscrowABI = [ { type: "constructor", - inputs: [], + inputs: [{ name: "_thawingPeriod", type: "uint256", internalType: "uint256" }], stateMutability: "nonpayable", }, + { + type: "function", + name: "DEPOSIT_AUTHORIZATION_TYPEHASH", + inputs: [], + outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], + stateMutability: "view", + }, { type: "function", name: "DOMAIN_SEPARATOR", inputs: [], - outputs: [ - { - name: "", - type: "bytes32", - internalType: "bytes32", - }, - ], + outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], stateMutability: "view", }, { type: "function", - name: "MAX_PPM", + name: "FLUSH_ALL_AUTHORIZATION_TYPEHASH", inputs: [], - outputs: [ - { - name: "", - type: "uint256", - internalType: "uint256", - }, - ], + outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], + stateMutability: "view", + }, + { + type: "function", + name: "FLUSH_AUTHORIZATION_TYPEHASH", + inputs: [], + outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], stateMutability: "view", }, { type: "function", name: "MAX_THAWING_PERIOD", inputs: [], - outputs: [ - { - name: "", - type: "uint256", - internalType: "uint256", - }, - ], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], stateMutability: "view", }, { type: "function", - name: "UPGRADE_INTERFACE_VERSION", + name: "THAWING_PERIOD", inputs: [], - outputs: [ - { - name: "", - type: "string", - internalType: "string", - }, - ], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], stateMutability: "view", }, { type: "function", name: "VOUCHER_TYPEHASH", inputs: [], - outputs: [ - { - name: "", - type: "bytes32", - internalType: "bytes32", - }, - ], + outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], stateMutability: "view", }, { type: "function", name: "cancelThaw", inputs: [ - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "asset", - type: "address", - internalType: "address", - }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, ], outputs: [], stateMutability: "nonpayable", @@ -96,63 +72,19 @@ export const deferredEscrowABI = [ type: "tuple", internalType: "struct IDeferredPaymentEscrow.Voucher", components: [ - { - name: "id", - type: "bytes32", - internalType: "bytes32", - }, - { - name: "buyer", - type: "address", - internalType: "address", - }, - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "valueAggregate", - type: "uint256", - internalType: "uint256", - }, - { - name: "asset", - type: "address", - internalType: "address", - }, - { - name: "timestamp", - type: "uint64", - internalType: "uint64", - }, - { - name: "nonce", - type: "uint256", - internalType: "uint256", - }, - { - name: "escrow", - type: "address", - internalType: "address", - }, - { - name: "chainId", - type: "uint256", - internalType: "uint256", - }, - { - name: "expiry", - type: "uint64", - internalType: "uint64", - }, + { name: "id", type: "bytes32", internalType: "bytes32" }, + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "valueAggregate", type: "uint256", internalType: "uint256" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "timestamp", type: "uint64", internalType: "uint64" }, + { name: "nonce", type: "uint256", internalType: "uint256" }, + { name: "escrow", type: "address", internalType: "address" }, + { name: "chainId", type: "uint256", internalType: "uint256" }, + { name: "expiry", type: "uint64", internalType: "uint64" }, ], }, - { - name: "signature", - type: "bytes", - internalType: "bytes", - }, + { name: "signature", type: "bytes", internalType: "bytes" }, ], outputs: [], stateMutability: "nonpayable", @@ -171,63 +103,19 @@ export const deferredEscrowABI = [ type: "tuple", internalType: "struct IDeferredPaymentEscrow.Voucher", components: [ - { - name: "id", - type: "bytes32", - internalType: "bytes32", - }, - { - name: "buyer", - type: "address", - internalType: "address", - }, - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "valueAggregate", - type: "uint256", - internalType: "uint256", - }, - { - name: "asset", - type: "address", - internalType: "address", - }, - { - name: "timestamp", - type: "uint64", - internalType: "uint64", - }, - { - name: "nonce", - type: "uint256", - internalType: "uint256", - }, - { - name: "escrow", - type: "address", - internalType: "address", - }, - { - name: "chainId", - type: "uint256", - internalType: "uint256", - }, - { - name: "expiry", - type: "uint64", - internalType: "uint64", - }, + { name: "id", type: "bytes32", internalType: "bytes32" }, + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "valueAggregate", type: "uint256", internalType: "uint256" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "timestamp", type: "uint64", internalType: "uint64" }, + { name: "nonce", type: "uint256", internalType: "uint256" }, + { name: "escrow", type: "address", internalType: "address" }, + { name: "chainId", type: "uint256", internalType: "uint256" }, + { name: "expiry", type: "uint64", internalType: "uint64" }, ], }, - { - name: "signature", - type: "bytes", - internalType: "bytes", - }, + { name: "signature", type: "bytes", internalType: "bytes" }, ], }, ], @@ -238,21 +126,9 @@ export const deferredEscrowABI = [ type: "function", name: "deposit", inputs: [ - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "asset", - type: "address", - internalType: "address", - }, - { - name: "amount", - type: "uint256", - internalType: "uint256", - }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "amount", type: "uint256", internalType: "uint256" }, ], outputs: [], stateMutability: "nonpayable", @@ -261,26 +137,14 @@ export const deferredEscrowABI = [ type: "function", name: "depositMany", inputs: [ - { - name: "asset", - type: "address", - internalType: "address", - }, + { name: "asset", type: "address", internalType: "address" }, { name: "deposits", type: "tuple[]", internalType: "struct IDeferredPaymentEscrow.DepositInput[]", components: [ - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "amount", - type: "uint256", - internalType: "uint256", - }, + { name: "seller", type: "address", internalType: "address" }, + { name: "amount", type: "uint256", internalType: "uint256" }, ], }, ], @@ -290,27 +154,33 @@ export const deferredEscrowABI = [ { type: "function", name: "depositTo", + inputs: [ + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "amount", type: "uint256", internalType: "uint256" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "depositWithAuthorization", inputs: [ { - name: "buyer", - type: "address", - internalType: "address", - }, - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "asset", - type: "address", - internalType: "address", - }, - { - name: "amount", - type: "uint256", - internalType: "uint256", + name: "auth", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.DepositAuthorization", + components: [ + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "amount", type: "uint256", internalType: "uint256" }, + { name: "nonce", type: "bytes32", internalType: "bytes32" }, + { name: "expiry", type: "uint64", internalType: "uint64" }, + ], }, + { name: "signature", type: "bytes", internalType: "bytes" }, ], outputs: [], stateMutability: "nonpayable", @@ -320,63 +190,63 @@ export const deferredEscrowABI = [ name: "eip712Domain", inputs: [], outputs: [ - { - name: "fields", - type: "bytes1", - internalType: "bytes1", - }, - { - name: "name", - type: "string", - internalType: "string", - }, - { - name: "version", - type: "string", - internalType: "string", - }, - { - name: "chainId", - type: "uint256", - internalType: "uint256", - }, - { - name: "verifyingContract", - type: "address", - internalType: "address", - }, - { - name: "salt", - type: "bytes32", - internalType: "bytes32", - }, - { - name: "extensions", - type: "uint256[]", - internalType: "uint256[]", - }, + { name: "fields", type: "bytes1", internalType: "bytes1" }, + { name: "name", type: "string", internalType: "string" }, + { name: "version", type: "string", internalType: "string" }, + { name: "chainId", type: "uint256", internalType: "uint256" }, + { name: "verifyingContract", type: "address", internalType: "address" }, + { name: "salt", type: "bytes32", internalType: "bytes32" }, + { name: "extensions", type: "uint256[]", internalType: "uint256[]" }, ], stateMutability: "view", }, { type: "function", - name: "getAccount", + name: "flushAllWithAuthorization", inputs: [ { - name: "buyer", - type: "address", - internalType: "address", - }, - { - name: "seller", - type: "address", - internalType: "address", + name: "auth", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.FlushAllAuthorization", + components: [ + { name: "buyer", type: "address", internalType: "address" }, + { name: "nonce", type: "bytes32", internalType: "bytes32" }, + { name: "expiry", type: "uint64", internalType: "uint64" }, + ], }, + { name: "signature", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "flushWithAuthorization", + inputs: [ { - name: "asset", - type: "address", - internalType: "address", + name: "auth", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.FlushAuthorization", + components: [ + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "nonce", type: "bytes32", internalType: "bytes32" }, + { name: "expiry", type: "uint64", internalType: "uint64" }, + ], }, + { name: "signature", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "getAccount", + inputs: [ + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, ], outputs: [ { @@ -384,21 +254,9 @@ export const deferredEscrowABI = [ type: "tuple", internalType: "struct IDeferredPaymentEscrow.EscrowAccount", components: [ - { - name: "balance", - type: "uint256", - internalType: "uint256", - }, - { - name: "thawingAmount", - type: "uint256", - internalType: "uint256", - }, - { - name: "thawEndTime", - type: "uint64", - internalType: "uint64", - }, + { name: "balance", type: "uint256", internalType: "uint256" }, + { name: "thawingAmount", type: "uint256", internalType: "uint256" }, + { name: "thawEndTime", type: "uint64", internalType: "uint64" }, ], }, ], @@ -413,70 +271,22 @@ export const deferredEscrowABI = [ type: "tuple", internalType: "struct IDeferredPaymentEscrow.Voucher", components: [ - { - name: "id", - type: "bytes32", - internalType: "bytes32", - }, - { - name: "buyer", - type: "address", - internalType: "address", - }, - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "valueAggregate", - type: "uint256", - internalType: "uint256", - }, - { - name: "asset", - type: "address", - internalType: "address", - }, - { - name: "timestamp", - type: "uint64", - internalType: "uint64", - }, - { - name: "nonce", - type: "uint256", - internalType: "uint256", - }, - { - name: "escrow", - type: "address", - internalType: "address", - }, - { - name: "chainId", - type: "uint256", - internalType: "uint256", - }, - { - name: "expiry", - type: "uint64", - internalType: "uint64", - }, + { name: "id", type: "bytes32", internalType: "bytes32" }, + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "valueAggregate", type: "uint256", internalType: "uint256" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "timestamp", type: "uint64", internalType: "uint64" }, + { name: "nonce", type: "uint256", internalType: "uint256" }, + { name: "escrow", type: "address", internalType: "address" }, + { name: "chainId", type: "uint256", internalType: "uint256" }, + { name: "expiry", type: "uint64", internalType: "uint64" }, ], }, ], outputs: [ - { - name: "outstanding", - type: "uint256", - internalType: "uint256", - }, - { - name: "collectable", - type: "uint256", - internalType: "uint256", - }, + { name: "outstanding", type: "uint256", internalType: "uint256" }, + { name: "collectable", type: "uint256", internalType: "uint256" }, ], stateMutability: "view", }, @@ -484,468 +294,197 @@ export const deferredEscrowABI = [ type: "function", name: "getVoucherCollected", inputs: [ - { - name: "buyer", - type: "address", - internalType: "address", - }, - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "voucherId", - type: "bytes32", - internalType: "bytes32", - }, - ], - outputs: [ - { - name: "", - type: "uint256", - internalType: "uint256", - }, + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "voucherId", type: "bytes32", internalType: "bytes32" }, ], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], stateMutability: "view", }, { type: "function", - name: "initialize", + name: "isDepositAuthorizationNonceUsed", inputs: [ - { - name: "_thawingPeriod", - type: "uint256", - internalType: "uint256", - }, - { - name: "_protocolFeePpm", - type: "uint256", - internalType: "uint256", - }, - { - name: "_protocolTreasury", - type: "address", - internalType: "address", - }, - { - name: "_owner", - type: "address", - internalType: "address", - }, + { name: "buyer", type: "address", internalType: "address" }, + { name: "nonce", type: "bytes32", internalType: "bytes32" }, ], - outputs: [], - stateMutability: "nonpayable", + outputs: [{ name: "", type: "bool", internalType: "bool" }], + stateMutability: "view", }, { type: "function", - name: "isSignatureValid", + name: "isDepositAuthorizationValid", inputs: [ { - name: "voucher", + name: "auth", type: "tuple", - internalType: "struct IDeferredPaymentEscrow.Voucher", + internalType: "struct IDeferredPaymentEscrow.DepositAuthorization", components: [ - { - name: "id", - type: "bytes32", - internalType: "bytes32", - }, - { - name: "buyer", - type: "address", - internalType: "address", - }, - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "valueAggregate", - type: "uint256", - internalType: "uint256", - }, - { - name: "asset", - type: "address", - internalType: "address", - }, - { - name: "timestamp", - type: "uint64", - internalType: "uint64", - }, - { - name: "nonce", - type: "uint256", - internalType: "uint256", - }, - { - name: "escrow", - type: "address", - internalType: "address", - }, - { - name: "chainId", - type: "uint256", - internalType: "uint256", - }, - { - name: "expiry", - type: "uint64", - internalType: "uint64", - }, + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "amount", type: "uint256", internalType: "uint256" }, + { name: "nonce", type: "bytes32", internalType: "bytes32" }, + { name: "expiry", type: "uint64", internalType: "uint64" }, ], }, - { - name: "signature", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [ - { - name: "", - type: "bool", - internalType: "bool", - }, + { name: "signature", type: "bytes", internalType: "bytes" }, ], + outputs: [{ name: "", type: "bool", internalType: "bool" }], stateMutability: "view", }, { type: "function", - name: "owner", - inputs: [], - outputs: [ - { - name: "", - type: "address", - internalType: "address", - }, + name: "isFlushAllAuthorizationNonceUsed", + inputs: [ + { name: "buyer", type: "address", internalType: "address" }, + { name: "nonce", type: "bytes32", internalType: "bytes32" }, ], + outputs: [{ name: "", type: "bool", internalType: "bool" }], stateMutability: "view", }, { type: "function", - name: "pause", - inputs: [], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "paused", - inputs: [], - outputs: [ + name: "isFlushAllAuthorizationValid", + inputs: [ { - name: "", - type: "bool", - internalType: "bool", + name: "auth", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.FlushAllAuthorization", + components: [ + { name: "buyer", type: "address", internalType: "address" }, + { name: "nonce", type: "bytes32", internalType: "bytes32" }, + { name: "expiry", type: "uint64", internalType: "uint64" }, + ], }, + { name: "signature", type: "bytes", internalType: "bytes" }, ], + outputs: [{ name: "", type: "bool", internalType: "bool" }], stateMutability: "view", }, { type: "function", - name: "protocolFeePpm", - inputs: [], - outputs: [ - { - name: "", - type: "uint256", - internalType: "uint256", - }, + name: "isFlushAuthorizationNonceUsed", + inputs: [ + { name: "buyer", type: "address", internalType: "address" }, + { name: "nonce", type: "bytes32", internalType: "bytes32" }, ], + outputs: [{ name: "", type: "bool", internalType: "bool" }], stateMutability: "view", }, { type: "function", - name: "protocolTreasury", - inputs: [], - outputs: [ + name: "isFlushAuthorizationValid", + inputs: [ { - name: "", - type: "address", - internalType: "address", + name: "auth", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.FlushAuthorization", + components: [ + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "nonce", type: "bytes32", internalType: "bytes32" }, + { name: "expiry", type: "uint64", internalType: "uint64" }, + ], }, + { name: "signature", type: "bytes", internalType: "bytes" }, ], + outputs: [{ name: "", type: "bool", internalType: "bool" }], stateMutability: "view", }, { type: "function", - name: "proxiableUUID", - inputs: [], - outputs: [ + name: "isVoucherSignatureValid", + inputs: [ { - name: "", - type: "bytes32", - internalType: "bytes32", + name: "voucher", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.Voucher", + components: [ + { name: "id", type: "bytes32", internalType: "bytes32" }, + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "valueAggregate", type: "uint256", internalType: "uint256" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "timestamp", type: "uint64", internalType: "uint64" }, + { name: "nonce", type: "uint256", internalType: "uint256" }, + { name: "escrow", type: "address", internalType: "address" }, + { name: "chainId", type: "uint256", internalType: "uint256" }, + { name: "expiry", type: "uint64", internalType: "uint64" }, + ], }, + { name: "signature", type: "bytes", internalType: "bytes" }, ], + outputs: [{ name: "", type: "bool", internalType: "bool" }], stateMutability: "view", }, { type: "function", - name: "renounceOwnership", - inputs: [], + name: "thaw", + inputs: [ + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "amount", type: "uint256", internalType: "uint256" }, + ], outputs: [], stateMutability: "nonpayable", }, - { - type: "function", - name: "setProtocolFee", - inputs: [ - { - name: "_protocolFeePpm", - type: "uint256", - internalType: "uint256", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "setProtocolTreasury", - inputs: [ - { - name: "_protocolTreasury", - type: "address", - internalType: "address", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "setThawingPeriod", - inputs: [ - { - name: "_thawingPeriod", - type: "uint256", - internalType: "uint256", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "thaw", - inputs: [ - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "asset", - type: "address", - internalType: "address", - }, - { - name: "amount", - type: "uint256", - internalType: "uint256", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "thawingPeriod", - inputs: [], - outputs: [ - { - name: "", - type: "uint256", - internalType: "uint256", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "transferOwnership", - inputs: [ - { - name: "newOwner", - type: "address", - internalType: "address", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "unpause", - inputs: [], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "upgradeToAndCall", - inputs: [ - { - name: "newImplementation", - type: "address", - internalType: "address", - }, - { - name: "data", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [], - stateMutability: "payable", - }, { type: "function", name: "withdraw", inputs: [ - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "asset", - type: "address", - internalType: "address", - }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, ], outputs: [], stateMutability: "nonpayable", }, { type: "event", - name: "Deposited", + name: "DepositAuthorized", inputs: [ - { - name: "buyer", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "seller", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "asset", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "amount", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - { - name: "newBalance", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "EIP712DomainChanged", - inputs: [], - anonymous: false, - }, - { - type: "event", - name: "Initialized", - inputs: [ - { - name: "version", - type: "uint64", - indexed: false, - internalType: "uint64", - }, + { name: "buyer", type: "address", indexed: true, internalType: "address" }, + { name: "seller", type: "address", indexed: true, internalType: "address" }, + { name: "asset", type: "address", indexed: true, internalType: "address" }, + { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }, + { name: "nonce", type: "bytes32", indexed: false, internalType: "bytes32" }, ], anonymous: false, }, { type: "event", - name: "OwnershipTransferred", - inputs: [ - { - name: "previousOwner", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "newOwner", - type: "address", - indexed: true, - internalType: "address", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "Paused", + name: "Deposited", inputs: [ - { - name: "account", - type: "address", - indexed: false, - internalType: "address", - }, + { name: "buyer", type: "address", indexed: true, internalType: "address" }, + { name: "seller", type: "address", indexed: true, internalType: "address" }, + { name: "asset", type: "address", indexed: true, internalType: "address" }, + { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }, + { name: "newBalance", type: "uint256", indexed: false, internalType: "uint256" }, ], anonymous: false, }, + { type: "event", name: "EIP712DomainChanged", inputs: [], anonymous: false }, { type: "event", - name: "ProtocolFeeUpdated", + name: "FlushAllAuthorized", inputs: [ - { - name: "oldFeePpm", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - { - name: "newFeePpm", - type: "uint256", - indexed: false, - internalType: "uint256", - }, + { name: "buyer", type: "address", indexed: true, internalType: "address" }, + { name: "nonce", type: "bytes32", indexed: false, internalType: "bytes32" }, + { name: "accountsFlushed", type: "uint256", indexed: false, internalType: "uint256" }, ], anonymous: false, }, { type: "event", - name: "ProtocolTreasuryUpdated", + name: "FlushAuthorized", inputs: [ - { - name: "oldTreasury", - type: "address", - indexed: false, - internalType: "address", - }, - { - name: "newTreasury", - type: "address", - indexed: false, - internalType: "address", - }, + { name: "buyer", type: "address", indexed: true, internalType: "address" }, + { name: "seller", type: "address", indexed: true, internalType: "address" }, + { name: "asset", type: "address", indexed: true, internalType: "address" }, + { name: "nonce", type: "bytes32", indexed: false, internalType: "bytes32" }, + { name: "thawing", type: "bool", indexed: false, internalType: "bool" }, ], anonymous: false, }, @@ -953,30 +492,10 @@ export const deferredEscrowABI = [ type: "event", name: "ThawCancelled", inputs: [ - { - name: "buyer", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "seller", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "asset", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "amount", - type: "uint256", - indexed: false, - internalType: "uint256", - }, + { name: "buyer", type: "address", indexed: true, internalType: "address" }, + { name: "seller", type: "address", indexed: true, internalType: "address" }, + { name: "asset", type: "address", indexed: true, internalType: "address" }, + { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }, ], anonymous: false, }, @@ -984,93 +503,13 @@ export const deferredEscrowABI = [ type: "event", name: "ThawInitiated", inputs: [ - { - name: "buyer", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "seller", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "asset", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "newThawingAmount", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - { - name: "previousThawingAmount", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - { - name: "newThawEndTime", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - { - name: "previousThawEndTime", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "ThawingPeriodUpdated", - inputs: [ - { - name: "oldPeriod", - type: "uint64", - indexed: false, - internalType: "uint64", - }, - { - name: "newPeriod", - type: "uint64", - indexed: false, - internalType: "uint64", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "Unpaused", - inputs: [ - { - name: "account", - type: "address", - indexed: false, - internalType: "address", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "Upgraded", - inputs: [ - { - name: "implementation", - type: "address", - indexed: true, - internalType: "address", - }, + { name: "buyer", type: "address", indexed: true, internalType: "address" }, + { name: "seller", type: "address", indexed: true, internalType: "address" }, + { name: "asset", type: "address", indexed: true, internalType: "address" }, + { name: "newThawingAmount", type: "uint256", indexed: false, internalType: "uint256" }, + { name: "previousThawingAmount", type: "uint256", indexed: false, internalType: "uint256" }, + { name: "newThawEndTime", type: "uint256", indexed: false, internalType: "uint256" }, + { name: "previousThawEndTime", type: "uint256", indexed: false, internalType: "uint256" }, ], anonymous: false, }, @@ -1078,36 +517,11 @@ export const deferredEscrowABI = [ type: "event", name: "VoucherAlreadyCollected", inputs: [ - { - name: "voucherId", - type: "bytes32", - indexed: true, - internalType: "bytes32", - }, - { - name: "buyer", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "seller", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "asset", - type: "address", - indexed: false, - internalType: "address", - }, - { - name: "totalCollected", - type: "uint256", - indexed: false, - internalType: "uint256", - }, + { name: "voucherId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "buyer", type: "address", indexed: true, internalType: "address" }, + { name: "seller", type: "address", indexed: true, internalType: "address" }, + { name: "asset", type: "address", indexed: false, internalType: "address" }, + { name: "totalCollected", type: "uint256", indexed: false, internalType: "uint256" }, ], anonymous: false, }, @@ -1115,48 +529,12 @@ export const deferredEscrowABI = [ type: "event", name: "VoucherCollected", inputs: [ - { - name: "voucherId", - type: "bytes32", - indexed: true, - internalType: "bytes32", - }, - { - name: "buyer", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "seller", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "asset", - type: "address", - indexed: false, - internalType: "address", - }, - { - name: "amount", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - { - name: "totalCollected", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - { - name: "protocolFee", - type: "uint256", - indexed: false, - internalType: "uint256", - }, + { name: "voucherId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "buyer", type: "address", indexed: true, internalType: "address" }, + { name: "seller", type: "address", indexed: true, internalType: "address" }, + { name: "asset", type: "address", indexed: false, internalType: "address" }, + { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }, + { name: "totalCollected", type: "uint256", indexed: false, internalType: "uint256" }, ], anonymous: false, }, @@ -1164,42 +542,12 @@ export const deferredEscrowABI = [ type: "event", name: "VoucherNoCollectableBalance", inputs: [ - { - name: "voucherId", - type: "bytes32", - indexed: true, - internalType: "bytes32", - }, - { - name: "buyer", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "seller", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "asset", - type: "address", - indexed: false, - internalType: "address", - }, - { - name: "outstanding", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - { - name: "alreadyCollected", - type: "uint256", - indexed: false, - internalType: "uint256", - }, + { name: "voucherId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "buyer", type: "address", indexed: true, internalType: "address" }, + { name: "seller", type: "address", indexed: true, internalType: "address" }, + { name: "asset", type: "address", indexed: false, internalType: "address" }, + { name: "outstanding", type: "uint256", indexed: false, internalType: "uint256" }, + { name: "alreadyCollected", type: "uint256", indexed: false, internalType: "uint256" }, ], anonymous: false, }, @@ -1207,340 +555,121 @@ export const deferredEscrowABI = [ type: "event", name: "Withdrawn", inputs: [ - { - name: "buyer", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "seller", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "asset", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "amount", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - { - name: "remainingBalance", - type: "uint256", - indexed: false, - internalType: "uint256", - }, + { name: "buyer", type: "address", indexed: true, internalType: "address" }, + { name: "seller", type: "address", indexed: true, internalType: "address" }, + { name: "asset", type: "address", indexed: true, internalType: "address" }, + { name: "amount", type: "uint256", indexed: false, internalType: "uint256" }, + { name: "remainingBalance", type: "uint256", indexed: false, internalType: "uint256" }, ], anonymous: false, }, { type: "error", - name: "AddressEmptyCode", + name: "AuthorizationExpired", inputs: [ - { - name: "target", - type: "address", - internalType: "address", - }, - ], - }, - { - type: "error", - name: "ERC1967InvalidImplementation", - inputs: [ - { - name: "implementation", - type: "address", - internalType: "address", - }, + { name: "expiry", type: "uint64", internalType: "uint64" }, + { name: "currentTime", type: "uint256", internalType: "uint256" }, ], }, - { - type: "error", - name: "ERC1967NonPayable", - inputs: [], - }, - { - type: "error", - name: "EnforcedPause", - inputs: [], - }, - { - type: "error", - name: "ExpectedPause", - inputs: [], - }, - { - type: "error", - name: "FailedCall", - inputs: [], - }, { type: "error", name: "InsufficientBalance", inputs: [ - { - name: "available", - type: "uint256", - internalType: "uint256", - }, - { - name: "requested", - type: "uint256", - internalType: "uint256", - }, + { name: "available", type: "uint256", internalType: "uint256" }, + { name: "requested", type: "uint256", internalType: "uint256" }, ], }, { type: "error", name: "InvalidAddress", - inputs: [ - { - name: "provided", - type: "address", - internalType: "address", - }, - ], + inputs: [{ name: "provided", type: "address", internalType: "address" }], }, { type: "error", name: "InvalidAmount", - inputs: [ - { - name: "provided", - type: "uint256", - internalType: "uint256", - }, - ], + inputs: [{ name: "provided", type: "uint256", internalType: "uint256" }], }, { type: "error", name: "InvalidAsset", - inputs: [ - { - name: "provided", - type: "address", - internalType: "address", - }, - ], + inputs: [{ name: "provided", type: "address", internalType: "address" }], }, + { type: "error", name: "InvalidAuthorization", inputs: [] }, { type: "error", name: "InvalidChainId", inputs: [ - { - name: "provided", - type: "uint256", - internalType: "uint256", - }, - { - name: "expected", - type: "uint256", - internalType: "uint256", - }, + { name: "provided", type: "uint256", internalType: "uint256" }, + { name: "expected", type: "uint256", internalType: "uint256" }, ], }, { type: "error", name: "InvalidEscrow", inputs: [ - { - name: "provided", - type: "address", - internalType: "address", - }, - { - name: "expected", - type: "address", - internalType: "address", - }, - ], - }, - { - type: "error", - name: "InvalidInitialization", - inputs: [], - }, - { - type: "error", - name: "InvalidProtocolFee", - inputs: [ - { - name: "provided", - type: "uint256", - internalType: "uint256", - }, - { - name: "maximum", - type: "uint256", - internalType: "uint256", - }, + { name: "provided", type: "address", internalType: "address" }, + { name: "expected", type: "address", internalType: "address" }, ], }, + { type: "error", name: "InvalidShortString", inputs: [] }, { type: "error", name: "InvalidSignature", inputs: [ - { - name: "voucherId", - type: "bytes32", - internalType: "bytes32", - }, - { - name: "buyer", - type: "address", - internalType: "address", - }, + { name: "voucherId", type: "bytes32", internalType: "bytes32" }, + { name: "buyer", type: "address", internalType: "address" }, ], }, { type: "error", name: "InvalidThawingPeriod", inputs: [ - { - name: "provided", - type: "uint256", - internalType: "uint256", - }, - { - name: "maximum", - type: "uint256", - internalType: "uint256", - }, + { name: "provided", type: "uint256", internalType: "uint256" }, + { name: "maximum", type: "uint256", internalType: "uint256" }, ], }, - { - type: "error", - name: "NoDepositsProvided", - inputs: [], - }, + { type: "error", name: "NoDepositsProvided", inputs: [] }, { type: "error", name: "NoThawingInProgress", inputs: [ - { - name: "buyer", - type: "address", - internalType: "address", - }, - { - name: "seller", - type: "address", - internalType: "address", - }, - { - name: "asset", - type: "address", - internalType: "address", - }, - ], - }, - { - type: "error", - name: "NoVouchersProvided", - inputs: [], - }, - { - type: "error", - name: "NotInitializing", - inputs: [], - }, - { - type: "error", - name: "OwnableInvalidOwner", - inputs: [ - { - name: "owner", - type: "address", - internalType: "address", - }, - ], - }, - { - type: "error", - name: "OwnableUnauthorizedAccount", - inputs: [ - { - name: "account", - type: "address", - internalType: "address", - }, + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, ], }, + { type: "error", name: "NoVouchersProvided", inputs: [] }, { type: "error", - name: "ReentrancyGuardReentrantCall", - inputs: [], + name: "NonceAlreadyUsed", + inputs: [{ name: "nonce", type: "bytes32", internalType: "bytes32" }], }, + { type: "error", name: "ReentrancyGuardReentrantCall", inputs: [] }, { type: "error", name: "SafeERC20FailedOperation", - inputs: [ - { - name: "token", - type: "address", - internalType: "address", - }, - ], + inputs: [{ name: "token", type: "address", internalType: "address" }], }, { type: "error", - name: "ThawingPeriodNotCompleted", - inputs: [ - { - name: "currentTime", - type: "uint256", - internalType: "uint256", - }, - { - name: "thawEndTime", - type: "uint256", - internalType: "uint256", - }, - ], + name: "StringTooLong", + inputs: [{ name: "str", type: "string", internalType: "string" }], }, { type: "error", - name: "UUPSUnauthorizedCallContext", - inputs: [], - }, - { - type: "error", - name: "UUPSUnsupportedProxiableUUID", + name: "ThawingPeriodNotCompleted", inputs: [ - { - name: "slot", - type: "bytes32", - internalType: "bytes32", - }, + { name: "currentTime", type: "uint256", internalType: "uint256" }, + { name: "thawEndTime", type: "uint256", internalType: "uint256" }, ], }, { type: "error", name: "VoucherExpired", inputs: [ - { - name: "voucherId", - type: "bytes32", - internalType: "bytes32", - }, - { - name: "currentTime", - type: "uint256", - internalType: "uint256", - }, - { - name: "expiry", - type: "uint256", - internalType: "uint256", - }, + { name: "voucherId", type: "bytes32", internalType: "bytes32" }, + { name: "currentTime", type: "uint256", internalType: "uint256" }, + { name: "expiry", type: "uint256", internalType: "uint256" }, ], }, ] as const; diff --git a/typescript/packages/x402/src/types/shared/evm/typedData.ts b/typescript/packages/x402/src/types/shared/evm/typedData.ts index 01f3c913c0..481d72aff0 100644 --- a/typescript/packages/x402/src/types/shared/evm/typedData.ts +++ b/typescript/packages/x402/src/types/shared/evm/typedData.ts @@ -19,7 +19,24 @@ export const typedDataTypes = { { name: "chainId", type: "uint256" }, { name: "expiry", type: "uint64" }, ], + Permit: [ + { name: "owner", type: "address" }, + { name: "spender", type: "address" }, + { name: "value", type: "uint256" }, + { name: "nonce", type: "uint256" }, + { name: "deadline", type: "uint256" }, + ], + DepositAuthorization: [ + { name: "buyer", type: "address" }, + { name: "seller", type: "address" }, + { name: "asset", type: "address" }, + { name: "amount", type: "uint256" }, + { name: "nonce", type: "bytes32" }, + { name: "expiry", type: "uint64" }, + ], }; export const transferWithAuthorizationPrimaryType = "TransferWithAuthorization" as const; export const deferredVoucherPrimaryType = "Voucher" as const; +export const permitPrimaryType = "Permit" as const; +export const depositAuthorizationPrimaryType = "DepositAuthorization" as const; diff --git a/typescript/packages/x402/src/types/verify/constants.ts b/typescript/packages/x402/src/types/verify/constants.ts index a1a912fc80..420f823aab 100644 --- a/typescript/packages/x402/src/types/verify/constants.ts +++ b/typescript/packages/x402/src/types/verify/constants.ts @@ -4,5 +4,6 @@ export const EvmAddressRegex = /^0x[0-9a-fA-F]{40}$/; export const SvmAddressRegex = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/; export const MixedAddressRegex = /^0x[a-fA-F0-9]{40}|[A-Za-z0-9][A-Za-z0-9-]{0,34}[A-Za-z0-9]$/; export const HexEncoded64ByteRegex = /^0x[0-9a-fA-F]{64}$/; +export const HexEncoded32ByteRegex = /^0x[0-9a-fA-F]{32}$/; export const EvmSignatureRegex = /^0x[0-9a-fA-F]+$/; // Flexible hex signature validation export const EvmTransactionHashRegex = /^0x[0-9a-fA-F]{64}$/; diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 131bbccce3..e7cf32a109 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -5,6 +5,7 @@ import { HexEncoded64ByteRegex, EvmMaxAtomicUnits, EvmTransactionHashRegex, + HexEncoded32ByteRegex, } from "../constants"; import { hasMaxLength, isInteger } from "../refiners"; import { BasePaymentPayloadSchema, BasePaymentRequirementsSchema } from "./base"; @@ -43,6 +44,15 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_voucher_error_settling_store", "invalid_deferred_evm_payload_voucher_not_found", "invalid_deferred_evm_payload_voucher_found_not_duplicate", + "invalid_deferred_evm_payload_permit_signature", + "invalid_deferred_evm_payload_deposit_authorization_signature", + "invalid_deferred_evm_payload_permit_continuity", + "invalid_deferred_evm_payload_deposit_authorization_continuity", + "invalid_deferred_evm_payload_deposit_authorization_cross_continuity", + "invalid_deferred_evm_contract_call_failed_nonces", + "invalid_deferred_evm_payload_permit_nonce_invalid", + "invalid_deferred_evm_payload_deposit_authorization_nonce_invalid", + "invalid_deferred_evm_contract_call_failed_is_deposit_authorization_nonce_used", ] as const; // x402DeferredEvmPayloadVoucher @@ -78,10 +88,67 @@ export const DeferredVoucherCollectionSchema = z.object({ }); export type DeferredVoucherCollection = z.infer; +// x402DeferredEscrowDepositAuthorizationPermit +export const DeferredEscrowDepositAuthorizationPermitSchema = z.object({ + owner: z.string().regex(EvmAddressRegex), + spender: z.string().regex(EvmAddressRegex), + value: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + nonce: z.string().regex(HexEncoded32ByteRegex), + deadline: z.number().int().nonnegative(), + domain: z.object({ + name: z.string(), + version: z.string(), + }), +}); +export type DeferredEscrowDepositAuthorizationPermit = z.infer< + typeof DeferredEscrowDepositAuthorizationPermitSchema +>; + +// x402DeferredEscrowDepositAuthorizationSignedPermit +export const DeferredEscrowDepositAuthorizationSignedPermitSchema = + DeferredEscrowDepositAuthorizationPermitSchema.extend({ + signature: z.string().regex(EvmSignatureRegex), + }); +export type DeferredEscrowDepositAuthorizationSignedPermit = z.infer< + typeof DeferredEscrowDepositAuthorizationSignedPermitSchema +>; + +// x402DeferredEscrowDepositAuthorizationInner +export const DeferredEscrowDepositAuthorizationInnerSchema = z.object({ + buyer: z.string().regex(EvmAddressRegex), + seller: z.string().regex(EvmAddressRegex), + asset: z.string().regex(EvmAddressRegex), + amount: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + nonce: z.string().regex(HexEncoded32ByteRegex), + expiry: z.number().int().nonnegative(), +}); +export type DeferredEscrowDepositAuthorizationInner = z.infer< + typeof DeferredEscrowDepositAuthorizationInnerSchema +>; + +// x402DeferredEscrowDepositAuthorizationSignedInner +export const DeferredEscrowDepositAuthorizationSignedInnerSchema = + DeferredEscrowDepositAuthorizationInnerSchema.extend({ + signature: z.string().regex(EvmSignatureRegex), + }); +export type DeferredEscrowDepositAuthorizationSignedInner = z.infer< + typeof DeferredEscrowDepositAuthorizationSignedInnerSchema +>; + +// x402DeferredEscrowDepositAuthorization +export const DeferredEscrowDepositAuthorizationSchema = z.object({ + permit: DeferredEscrowDepositAuthorizationSignedPermitSchema, + depositAuthorization: DeferredEscrowDepositAuthorizationSignedInnerSchema, +}); +export type DeferredEscrowDepositAuthorization = z.infer< + typeof DeferredEscrowDepositAuthorizationSchema +>; + // x402DeferredEvmPayload export const DeferredEvmPayloadSchema = z.object({ signature: z.string().regex(EvmSignatureRegex), voucher: DeferredEvmPayloadVoucherSchema, + depositAuthorization: DeferredEscrowDepositAuthorizationSchema.optional(), }); export type DeferredEvmPayload = z.infer; From 4ff377ab0c06b09e8adc1a4962a162bc78a4b057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 3 Oct 2025 09:57:44 -0300 Subject: [PATCH 087/116] test: fix deferred integration tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/schemes/deferred/evm/integration.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts index 80fee59bd4..1b27d1cc9b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts @@ -345,6 +345,7 @@ describe("Deferred Payment Integration Tests", () => { {}, ); expect(voucherCollections.length).toBe(1); + console.log(voucherCollections); expect(voucherCollections[0]).toEqual({ voucherId: decodedPaymentPayload.payload.voucher.id, voucherNonce: decodedPaymentPayload.payload.voucher.nonce, @@ -443,9 +444,9 @@ function mockBlockchainInteractionsSettle(wallet: SignerWallet status: "success", logs: [ { - data: "0x000000000000000000000000036cbd53842c5426634e7929541ec2318f3dcf7e00000000000000000000000000000000000000000000000000000000000003f900000000000000000000000000000000000000000000000000000000000003f90000000000000000000000000000000000000000000000000000000000000000", + data: "0x000000000000000000000000111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000003f900000000000000000000000000000000000000000000000000000000000003f9", topics: [ - "0x70696cf682404a5a47c0a00d3253721b5c093ff0a4c8a13374f53712fc481d77", + "0x9cc196634f792f4e61cf0cd71e2fbbd459e54c5e57a9bad3e6f7b6e79503cc70", "0x198e73e1cecf59db4fbf8ca10000000000000000000000000000000000000000", "0x00000000000000000000000080cdf1957ebb7a2df22dd8913753a4423ff4272e", "0x000000000000000000000000c93d37ad45c907ee1b27a02b2e1bd823ba9d379c", From 06217ad5d6f4128f4c8db4a47bf8932aaa916c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 3 Oct 2025 10:13:38 -0300 Subject: [PATCH 088/116] test: make deferred integration tests less brittle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../schemes/deferred/evm/integration.test.ts | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts index 1b27d1cc9b..71f5ab9be3 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts @@ -430,15 +430,25 @@ describe("Deferred Payment Integration Tests", () => { * @param wallet - The wallet to mock blockchain interactions for */ function mockBlockchainInteractionsSettle(wallet: SignerWallet) { - vi.mocked(wallet.readContract) - .mockResolvedValueOnce([BigInt(1_000_000)]) - .mockResolvedValueOnce({ - balance: BigInt(10_000_000), - }) - .mockResolvedValueOnce([BigInt(1_000_000)]) - .mockResolvedValueOnce({ - balance: BigInt(10_000_000), - }); + vi.mocked(wallet.readContract).mockImplementation(async (args: { functionName: string }) => { + if (args.functionName === "getOutstandingAndCollectableAmount") { + return [BigInt(1_000_000)]; + } + if (args.functionName === "getAccount") { + return { + balance: BigInt(10_000_000), + thawingAmount: BigInt(0), + thawEndTime: BigInt(0), + }; + } + if (args.functionName === "nonces") { + return BigInt(0); + } + if (args.functionName === "isDepositAuthorizationNonceUsed") { + return false; + } + throw new Error(`Unmocked contract read: ${args.functionName}`); + }); vi.mocked(wallet.writeContract).mockResolvedValue("0x1234567890abcdef"); vi.mocked(wallet.waitForTransactionReceipt).mockResolvedValue({ status: "success", @@ -462,9 +472,23 @@ function mockBlockchainInteractionsSettle(wallet: SignerWallet * @param wallet - The wallet to mock blockchain interactions for */ function mockBlockchainInteractionsVerify(wallet: SignerWallet) { - vi.mocked(wallet.readContract) - .mockResolvedValueOnce([BigInt(1_000_000)]) - .mockResolvedValueOnce({ - balance: BigInt(10_000_000), - }); + vi.mocked(wallet.readContract).mockImplementation(async (args: { functionName: string }) => { + if (args.functionName === "getOutstandingAndCollectableAmount") { + return [BigInt(1_000_000)]; + } + if (args.functionName === "getAccount") { + return { + balance: BigInt(10_000_000), + thawingAmount: BigInt(0), + thawEndTime: BigInt(0), + }; + } + if (args.functionName === "nonces") { + return BigInt(0); + } + if (args.functionName === "isDepositAuthorizationNonceUsed") { + return false; + } + throw new Error(`Unmocked contract read: ${args.functionName}`); + }); } From b1c2f941e6f83498ef402c16adc43077ae31062b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 3 Oct 2025 15:01:35 -0300 Subject: [PATCH 089/116] feat(deferred): add facilitator logic to execute deposit with auth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../schemes/deferred/evm/facilitator.test.ts | 234 ++++++++++++++++- .../src/schemes/deferred/evm/facilitator.ts | 147 ++++++++++- .../schemes/deferred/evm/integration.test.ts | 138 +++++++++- .../src/schemes/deferred/evm/sign.test.ts | 245 +++++++++++++++++- .../src/schemes/deferred/evm/verify.test.ts | 173 +++++++++++++ .../x402/src/types/verify/constants.ts | 1 - .../x402/src/types/verify/schemes/deferred.ts | 6 +- 7 files changed, 934 insertions(+), 10 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts index 4696328d25..82da4ca147 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts @@ -1,9 +1,9 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { Chain, Log, Transport } from "viem"; +import { Address, Chain, Log, Transport } from "viem"; import { createSigner, ConnectedClient, SignerWallet } from "../../../types/shared/evm"; import { PaymentRequirements, SchemeContext } from "../../../types/verify"; import { DeferredPaymentPayload, DEFERRRED_SCHEME } from "../../../types/verify/schemes/deferred"; -import { verify, settle, settleVoucher } from "./facilitator"; +import { verify, settle, settleVoucher, depositWithAuthorization } from "./facilitator"; import { VoucherStore } from "./store"; import * as verifyModule from "./verify"; @@ -14,6 +14,7 @@ vi.mock("./verify", () => ({ verifyVoucherSignature: vi.fn(), verifyVoucherAvailability: vi.fn(), verifyOnchainState: vi.fn(), + verifyDepositAuthorization: vi.fn(), })); const buyer = createSigner( @@ -580,3 +581,232 @@ describe("facilitator - settleVoucher", () => { ); }); }); + +describe("facilitator - depositWithAuthorization", () => { + const mockVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + }; + + const mockDepositAuthorization = { + permit: { + owner: buyerAddress, + spender: escrowAddress, + value: "1000000", + nonce: 0, + deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, + domain: { + name: "USD Coin", + version: "2", + }, + signature: + "0x1ed1158f8c70dc6393f8c9a379bf4569eb13a0ae6f060465418cbb9acbf5fb536eda5bdb7a6a28317329df0b9aec501fdf15f02f04b60ac536b90da3ce6f3efb1c", + }, + depositAuthorization: { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "1000000", + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b", + }, + }; + + let mockWallet: SignerWallet; + + beforeEach(() => { + vi.clearAllMocks(); + + // Mock successful verification by default + vi.mocked(verifyModule.verifyDepositAuthorization).mockResolvedValue({ isValid: true }); + + // Create a proper mock wallet with all required properties + mockWallet = { + account: { + address: buyerAddress, + }, + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn().mockResolvedValue("0x1234567890abcdef"), + waitForTransactionReceipt: vi.fn().mockResolvedValue({ + status: "success", + logs: [], + }), + } as unknown as SignerWallet; + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it("should deposit with authorization successfully", async () => { + const result = await depositWithAuthorization( + mockWallet, + mockVoucher, + mockDepositAuthorization, + ); + + expect(result).toEqual({ + success: true, + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + + // Should have called writeContract twice (permit + depositWithAuthorization) + expect(mockWallet.writeContract).toHaveBeenCalledTimes(2); + + // Verify permit call - args: [owner, spender, value, deadline, v, r, s] + const permitCall = vi.mocked(mockWallet.writeContract).mock.calls[0][0]; + expect(permitCall).toMatchObject({ + address: assetAddress, + functionName: "permit", + chain: mockWallet.chain, + }); + expect(permitCall.args).toHaveLength(7); + expect(permitCall.args?.[0]).toBe(buyerAddress); + expect((permitCall.args?.[1] as Address).toLowerCase()).toBe(escrowAddress.toLowerCase()); + expect(permitCall.args?.[2]).toBe(BigInt("1000000")); + expect(permitCall.args?.[3]).toBe(BigInt(mockDepositAuthorization.permit.deadline)); + + // Verify depositWithAuthorization call + const depositCall = vi.mocked(mockWallet.writeContract).mock.calls[1][0]; + expect(depositCall).toMatchObject({ + address: escrowAddress, + functionName: "depositWithAuthorization", + chain: mockWallet.chain, + }); + expect(depositCall.args).toHaveLength(2); + expect(depositCall.args?.[0]).toMatchObject({ + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: BigInt("1000000"), + }); + + // Should have waited for both receipts + expect(mockWallet.waitForTransactionReceipt).toHaveBeenCalledTimes(2); + }); + + it("should return error when deposit authorization verification fails", async () => { + vi.mocked(verifyModule.verifyDepositAuthorization).mockResolvedValue({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_permit_signature", + }); + + const result = await depositWithAuthorization( + mockWallet, + mockVoucher, + mockDepositAuthorization, + ); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_deferred_evm_payload_permit_signature", + transaction: "", + payer: buyerAddress, + }); + + // Should not have called any contract writes + expect(mockWallet.writeContract).not.toHaveBeenCalled(); + }); + + it("should return error when permit transaction fails", async () => { + mockWallet.writeContract = vi.fn().mockRejectedValueOnce(new Error("Permit failed")); + + const result = await depositWithAuthorization( + mockWallet, + mockVoucher, + mockDepositAuthorization, + ); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_transaction_reverted", + transaction: "", + payer: buyerAddress, + }); + + // Should have only called writeContract once (permit failed) + expect(mockWallet.writeContract).toHaveBeenCalledTimes(1); + }); + + it("should return error when permit transaction receipt shows failure", async () => { + mockWallet.waitForTransactionReceipt = vi + .fn() + .mockResolvedValueOnce({ status: "reverted", logs: [] }); + + const result = await depositWithAuthorization( + mockWallet, + mockVoucher, + mockDepositAuthorization, + ); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_transaction_state", + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + + // Should have only called writeContract once (permit succeeded but reverted) + expect(mockWallet.writeContract).toHaveBeenCalledTimes(1); + expect(mockWallet.waitForTransactionReceipt).toHaveBeenCalledTimes(1); + }); + + it("should return error when depositWithAuthorization transaction fails", async () => { + mockWallet.writeContract = vi + .fn() + .mockResolvedValueOnce("0x1234567890abcdef") // permit succeeds + .mockRejectedValueOnce(new Error("Deposit failed")); // depositWithAuthorization fails + + const result = await depositWithAuthorization( + mockWallet, + mockVoucher, + mockDepositAuthorization, + ); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_transaction_reverted", + transaction: "", + payer: buyerAddress, + }); + + // Should have called writeContract twice + expect(mockWallet.writeContract).toHaveBeenCalledTimes(2); + }); + + it("should return error when depositWithAuthorization receipt shows failure", async () => { + mockWallet.waitForTransactionReceipt = vi + .fn() + .mockResolvedValueOnce({ status: "success", logs: [] }) // permit succeeds + .mockResolvedValueOnce({ status: "reverted", logs: [] }); // depositWithAuthorization reverts + + const result = await depositWithAuthorization( + mockWallet, + mockVoucher, + mockDepositAuthorization, + ); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_transaction_state", + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + + // Should have completed both transactions + expect(mockWallet.writeContract).toHaveBeenCalledTimes(2); + expect(mockWallet.waitForTransactionReceipt).toHaveBeenCalledTimes(2); + }); +}); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 266a234bb1..7fff421c81 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -1,4 +1,13 @@ -import { Account, Address, Chain, Transport, Hex, parseEventLogs } from "viem"; +import { + Account, + parseSignature, + Address, + Chain, + Transport, + Hex, + parseEventLogs, + getAddress, +} from "viem"; import { ConnectedClient, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, @@ -15,12 +24,14 @@ import { DeferredSchemeContextSchema, } from "../../../types/verify/schemes/deferred"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; +import { usdcABI } from "../../../types/shared/evm/erc20PermitABI"; import { verifyPaymentRequirements, verifyVoucherSignature, verifyOnchainState, verifyVoucherContinuity, verifyVoucherAvailability, + verifyDepositAuthorization, } from "./verify"; import { VoucherStore } from "./store"; @@ -141,6 +152,25 @@ export async function settle( }; } + if (paymentPayload.payload.depositAuthorization) { + const depositAuthorizationResponse = await depositWithAuthorization( + wallet, + paymentPayload.payload.voucher, + paymentPayload.payload.depositAuthorization, + ); + if (!depositAuthorizationResponse.success) { + return { + success: false, + network: paymentPayload.network, + transaction: "", + errorReason: + depositAuthorizationResponse.errorReason ?? + "invalid_deferred_evm_payload_deposit_authorization_failed", + payer: paymentPayload.payload.voucher.buyer, + }; + } + } + const { voucher, signature, depositAuthorization } = paymentPayload.payload; const response = await settleVoucher( wallet, @@ -292,3 +322,118 @@ export async function settleVoucher( + wallet: SignerWallet, + voucher: DeferredEvmPayloadVoucher, + depositAuthorization: DeferredEscrowDepositAuthorization, +): Promise { + // Verify the deposit authorization + const valid = await verifyDepositAuthorization(wallet, voucher, depositAuthorization); + if (!valid.isValid) { + return { + success: false, + errorReason: valid.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", + transaction: "", + payer: depositAuthorization.permit.owner, + }; + } + + const { permit, depositAuthorization: depositAuthorizationInnerWithSignature } = + depositAuthorization; + const { v, r, s, yParity } = parseSignature(permit.signature as `0x${string}`); + const { signature: depositAuthorizationSignature, ...depositAuthorizationInner } = + depositAuthorizationInnerWithSignature; + + // Send permit() transaction + let permitTx = ""; + try { + permitTx = await wallet.writeContract({ + address: voucher.asset as Address, + abi: usdcABI, + functionName: "permit" as const, + args: [ + getAddress(permit.owner), + getAddress(permit.spender), + BigInt(permit.value), + BigInt(permit.deadline), + Number(v ?? (yParity === 0 ? 27n : 28n)), + r, + s, + ], + chain: wallet.chain as Chain, + }); + } catch (error) { + console.error(error); + return { + success: false, + errorReason: "invalid_transaction_reverted", + transaction: "", + payer: depositAuthorization.permit.owner, + }; + } + + const permitReceipt = await wallet.waitForTransactionReceipt({ hash: permitTx as `0x${string}` }); + if (permitReceipt.status !== "success") { + return { + success: false, + errorReason: "invalid_transaction_state", + transaction: permitTx, + payer: depositAuthorization.permit.owner, + }; + } + + // Send depositWithAuthorization() transaction + let tx = ""; + try { + tx = await wallet.writeContract({ + address: voucher.escrow as Address, + abi: deferredEscrowABI, + functionName: "depositWithAuthorization" as const, + args: [ + { + buyer: getAddress(depositAuthorizationInner.buyer), + seller: getAddress(depositAuthorizationInner.seller), + asset: getAddress(depositAuthorizationInner.asset), + amount: BigInt(depositAuthorizationInner.amount), + nonce: depositAuthorizationInner.nonce as `0x${string}`, + expiry: BigInt(depositAuthorizationInner.expiry), + }, + depositAuthorizationSignature as `0x${string}`, + ], + chain: wallet.chain as Chain, + }); + } catch (error) { + console.error(error); + return { + success: false, + errorReason: "invalid_transaction_reverted", + transaction: "", + payer: voucher.buyer, + }; + } + + const receipt = await wallet.waitForTransactionReceipt({ hash: tx as `0x${string}` }); + if (receipt.status !== "success") { + return { + success: false, + errorReason: "invalid_transaction_state", + transaction: tx, + payer: depositAuthorizationInner.buyer, + }; + } + + return { + success: true, + transaction: tx, + payer: depositAuthorization.permit.owner, + }; +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts index 71f5ab9be3..cee8249117 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts @@ -4,13 +4,16 @@ import { DeferredPaymentPayload, DeferredPaymentRequirements, DEFERRRED_SCHEME, + DeferredEscrowDepositAuthorization, } from "../../../types/verify/schemes/deferred"; -import { createPayment, createPaymentHeader } from "./client"; +import { createPayment } from "./client"; import { decodePayment } from "./utils/paymentUtils"; import { settle, verify } from "./facilitator"; import { InMemoryVoucherStore } from "./store.mock"; import { getPaymentRequirementsExtra } from "./server"; import { Chain, Log, TransactionReceipt, Transport } from "viem"; +import { signPermit, signDepositAuthorizationInner } from "./sign"; +import { createPaymentHeader } from "../../../client"; describe("Deferred Payment Integration Tests", () => { const sellerAddress = "0x1234567890123456789012345678901234567890"; @@ -345,7 +348,6 @@ describe("Deferred Payment Integration Tests", () => { {}, ); expect(voucherCollections.length).toBe(1); - console.log(voucherCollections); expect(voucherCollections[0]).toEqual({ voucherId: decodedPaymentPayload.payload.voucher.id, voucherNonce: decodedPaymentPayload.payload.voucher.nonce, @@ -356,6 +358,138 @@ describe("Deferred Payment Integration Tests", () => { collectedAt: expect.any(Number), }); }); + + it("should handle payment lifecycle with depositAuthorization", async () => { + // Initialize facilitator + const voucherStore = new InMemoryVoucherStore(); + const facilitatorWallet = { + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn(), + waitForTransactionReceipt: vi.fn(), + } as unknown as SignerWallet; + + // Create buyer + const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const buyerAddress = buyer.account.address; + + // Create deposit authorization (permit + depositAuth) + const now = Math.floor(Date.now() / 1000); + const oneWeek = 604800; + const depositAmount = "5000"; + + const permit = { + owner: buyerAddress, + spender: escrowAddress, + value: depositAmount, + nonce: 0, + deadline: now + oneWeek * 2, + domain: { + name: "USD Coin", + version: "2", + }, + }; + + const permitSignature = await signPermit(buyer, permit, 84532, assetAddress); + + const depositAuthInner = { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: depositAmount, + nonce: "0x0000000000000000000000000000000000000000000000000000000000000001", + expiry: now + oneWeek * 2, + }; + + const depositAuthSignature = await signDepositAuthorizationInner( + buyer, + depositAuthInner, + 84532, + escrowAddress, + ); + + const depositAuthorization: DeferredEscrowDepositAuthorization = { + permit: { + ...permit, + signature: permitSignature.signature, + }, + depositAuthorization: { + ...depositAuthInner, + signature: depositAuthSignature.signature, + }, + }; + + // * Step 1: Payment requirements generation + const paymentRequirements = { + ...basePaymentRequirements, + extra: await getPaymentRequirementsExtra( + undefined, + buyerAddress, + sellerAddress, + escrowAddress, + (buyer, seller) => voucherStore.getAvailableVoucher(buyer, seller), + ), + } as DeferredPaymentRequirements; + + expect(paymentRequirements.extra.type).toBe("new"); + + // * Step 2: Create payment with deposit authorization + const paymentPayload = (await createPayment( + buyer, + 1, + paymentRequirements, + )) as DeferredPaymentPayload; + + // Manually add depositAuthorization to the payload + const payloadWithAuth: DeferredPaymentPayload = { + ...paymentPayload, + payload: { + ...paymentPayload.payload, + depositAuthorization, + }, + }; + + // * Step 3: Verify payment with deposit authorization + mockBlockchainInteractionsVerify(facilitatorWallet); + const verifyResponse = await verify(facilitatorWallet, payloadWithAuth, paymentRequirements, { + deferred: { voucherStore }, + }); + expect(verifyResponse.isValid).toBe(true); + + // * Step 4: Store voucher + voucherStore.storeVoucher({ + ...payloadWithAuth.payload.voucher, + signature: payloadWithAuth.payload.signature, + }); + + // * Step 5: Settle with deposit authorization + mockBlockchainInteractionsSettle(facilitatorWallet); + const settleResponse = await settle(facilitatorWallet, payloadWithAuth, paymentRequirements, { + deferred: { voucherStore }, + }); + expect(settleResponse.success).toBe(true); + + const voucherCollections = await voucherStore.getVoucherCollections( + { + id: payloadWithAuth.payload.voucher.id, + nonce: payloadWithAuth.payload.voucher.nonce, + }, + {}, + ); + expect(voucherCollections.length).toBe(1); + expect(voucherCollections[0]).toEqual({ + voucherId: payloadWithAuth.payload.voucher.id, + voucherNonce: payloadWithAuth.payload.voucher.nonce, + chainId: payloadWithAuth.payload.voucher.chainId, + transactionHash: settleResponse.transaction, + collectedAmount: payloadWithAuth.payload.voucher.valueAggregate, + asset: payloadWithAuth.payload.voucher.asset, + collectedAt: expect.any(Number), + }); + }); }); describe("Multi-round voucher aggregation", () => { diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts index e9f8fb2dba..0aa7f0da5d 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts @@ -1,6 +1,13 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createSigner } from "../../../types/shared/evm"; -import { signVoucher, verifyVoucher } from "./sign"; +import { + signVoucher, + verifyVoucher, + signPermit, + verifyPermit, + signDepositAuthorizationInner, + verifyDepositAuthorizationInner, +} from "./sign"; import { privateKeyToAccount } from "viem/accounts"; const buyer = createSigner( @@ -101,3 +108,239 @@ describe("voucher signature", () => { ); }); }); + +describe("permit signature", () => { + const mockPermit = { + owner: buyerAddress, + spender: escrowAddress, + value: "1000000", + nonce: 0, + deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days + domain: { + name: "USD Coin", + version: "2", + }, + }; + + const mockPermitSignature = + "0x1ed1158f8c70dc6393f8c9a379bf4569eb13a0ae6f060465418cbb9acbf5fb536eda5bdb7a6a28317329df0b9aec501fdf15f02f04b60ac536b90da3ce6f3efb1c"; + + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2024-01-01T00:00:00Z")); + vi.clearAllMocks(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it("should create a valid permit signature", async () => { + const signature = await signPermit(buyer, mockPermit, 84532, assetAddress as `0x${string}`); + expect(signature.signature).toBe(mockPermitSignature); + }); + + it("should verify a valid permit signature", async () => { + const isValid = await verifyPermit( + mockPermit, + mockPermitSignature as `0x${string}`, + buyerAddress as `0x${string}`, + 84532, + assetAddress as `0x${string}`, + ); + expect(isValid).toBe(true); + }); + + it("should return false if permit signature is valid but for a different signer", async () => { + const isValid = await verifyPermit( + mockPermit, + mockPermitSignature as `0x${string}`, + anotherBuyerAddress as `0x${string}`, + 84532, + assetAddress as `0x${string}`, + ); + expect(isValid).toBe(false); + }); + + it("should sign a permit using a LocalAccount", async () => { + const localAccount = privateKeyToAccount( + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const signature = await signPermit( + localAccount, + mockPermit, + 84532, + assetAddress as `0x${string}`, + ); + + expect(signature.signature).toBe(mockPermitSignature); + }); + + it("should verify a permit signed by a LocalAccount", async () => { + const localAccount = privateKeyToAccount( + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const signature = await signPermit( + localAccount, + mockPermit, + 84532, + assetAddress as `0x${string}`, + ); + + const isValid = await verifyPermit( + mockPermit, + signature.signature, + localAccount.address, + 84532, + assetAddress as `0x${string}`, + ); + expect(isValid).toBe(true); + }); + + it("should throw error if wallet client does not support signTypedData", async () => { + const invalidWallet = { + account: { address: buyerAddress }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + + await expect( + signPermit(invalidWallet, mockPermit, 84532, assetAddress as `0x${string}`), + ).rejects.toThrow("Invalid wallet client provided does not support signTypedData"); + }); + + it("should throw error if LocalAccount does not support signTypedData", async () => { + const invalidAccount = { + address: buyerAddress, + type: "local", + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + + await expect( + signPermit(invalidAccount, mockPermit, 84532, assetAddress as `0x${string}`), + ).rejects.toThrow("Invalid wallet client provided does not support signTypedData"); + }); +}); + +describe("deposit authorization signature", () => { + const mockDepositAuth = { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "1000000", + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days + }; + + const mockDepositAuthSignature = + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b"; + + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2024-01-01T00:00:00Z")); + vi.clearAllMocks(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it("should create a valid deposit authorization signature", async () => { + const signature = await signDepositAuthorizationInner( + buyer, + mockDepositAuth, + 84532, + escrowAddress as `0x${string}`, + ); + expect(signature.signature).toBe(mockDepositAuthSignature); + }); + + it("should verify a valid deposit authorization signature", async () => { + const isValid = await verifyDepositAuthorizationInner( + mockDepositAuth, + mockDepositAuthSignature as `0x${string}`, + buyerAddress as `0x${string}`, + 84532, + escrowAddress as `0x${string}`, + ); + expect(isValid).toBe(true); + }); + + it("should return false if deposit authorization signature is valid but for a different signer", async () => { + const isValid = await verifyDepositAuthorizationInner( + mockDepositAuth, + mockDepositAuthSignature as `0x${string}`, + anotherBuyerAddress as `0x${string}`, + 84532, + escrowAddress as `0x${string}`, + ); + expect(isValid).toBe(false); + }); + + it("should sign a deposit authorization using a LocalAccount", async () => { + const localAccount = privateKeyToAccount( + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const signature = await signDepositAuthorizationInner( + localAccount, + mockDepositAuth, + 84532, + escrowAddress as `0x${string}`, + ); + + expect(signature.signature).toBe(mockDepositAuthSignature); + }); + + it("should verify a deposit authorization signed by a LocalAccount", async () => { + const localAccount = privateKeyToAccount( + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const signature = await signDepositAuthorizationInner( + localAccount, + mockDepositAuth, + 84532, + escrowAddress as `0x${string}`, + ); + + const isValid = await verifyDepositAuthorizationInner( + mockDepositAuth, + signature.signature, + localAccount.address, + 84532, + escrowAddress as `0x${string}`, + ); + expect(isValid).toBe(true); + }); + + it("should throw error if wallet client does not support signTypedData", async () => { + const invalidWallet = { + account: { address: buyerAddress }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + + await expect( + signDepositAuthorizationInner( + invalidWallet, + mockDepositAuth, + 84532, + escrowAddress as `0x${string}`, + ), + ).rejects.toThrow("Invalid wallet client provided does not support signTypedData"); + }); + + it("should throw error if LocalAccount does not support signTypedData", async () => { + const invalidAccount = { + address: buyerAddress, + type: "local", + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + + await expect( + signDepositAuthorizationInner( + invalidAccount, + mockDepositAuth, + 84532, + escrowAddress as `0x${string}`, + ), + ).rejects.toThrow("Invalid wallet client provided does not support signTypedData"); + }); +}); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts index 29e365d17e..568aa90c08 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts @@ -13,6 +13,7 @@ import { verifyVoucherContinuity, verifyVoucherAvailability, verifyVoucherDuplicate, + verifyDepositAuthorization, } from "./verify"; import { ConnectedClient, createSigner } from "../../../types/shared/evm/wallet"; import { getNetworkId } from "../../../shared"; @@ -1212,3 +1213,175 @@ describe("verifyOnchainState", () => { }); }); }); + +describe("verifyDepositAuthorization", () => { + const mockVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days + }; + + const mockDepositAuthorization = { + permit: { + owner: buyerAddress, + spender: escrowAddress, + value: "1000000", + nonce: 0, + deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, + domain: { + name: "USD Coin", + version: "2", + }, + signature: + "0x1ed1158f8c70dc6393f8c9a379bf4569eb13a0ae6f060465418cbb9acbf5fb536eda5bdb7a6a28317329df0b9aec501fdf15f02f04b60ac536b90da3ce6f3efb1c" as `0x${string}`, + }, + depositAuthorization: { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "1000000", + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" as `0x${string}`, + }, + }; + + let mockClient: ConnectedClient; + + beforeEach(() => { + vi.clearAllMocks(); + vi.useFakeTimers(); + vi.setSystemTime(new Date(mockVoucher.timestamp * 1000 + 100000)); // 100 seconds after voucher timestamp + mockClient = { + chain: { id: 84532 }, + readContract: vi.fn(), + } as unknown as ConnectedClient; + }); + + afterEach(() => { + vi.useRealTimers(); + vi.resetAllMocks(); + }); + + it("should return valid if deposit authorization is valid", async () => { + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce(BigInt(0)) // permit nonce + .mockResolvedValueOnce(false); // deposit authorization nonce not used + + const result = await verifyDepositAuthorization( + mockClient, + mockVoucher, + mockDepositAuthorization, + ); + expect(result).toEqual({ isValid: true }); + }); + + it("should return error if permit signature is invalid", async () => { + const invalidPermit = { + ...mockDepositAuthorization, + permit: { + ...mockDepositAuthorization.permit, + signature: + "0x999b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c" as `0x${string}`, + }, + }; + + const result = await verifyDepositAuthorization(mockClient, mockVoucher, invalidPermit); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_permit_signature", + payer: buyerAddress, + }); + }); + + it("should return error if deposit authorization signature is invalid", async () => { + const invalidDepositAuth = { + ...mockDepositAuthorization, + depositAuthorization: { + ...mockDepositAuthorization.depositAuthorization, + signature: + "0x999b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c" as `0x${string}`, + }, + }; + + const result = await verifyDepositAuthorization(mockClient, mockVoucher, invalidDepositAuth); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_signature", + payer: buyerAddress, + }); + }); + + it("should return error if permit nonce is invalid", async () => { + vi.mocked(mockClient.readContract).mockResolvedValueOnce(BigInt(5)); // Different nonce + + const result = await verifyDepositAuthorization( + mockClient, + mockVoucher, + mockDepositAuthorization, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_permit_nonce_invalid", + payer: buyerAddress, + }); + }); + + it("should return error if permit nonce check fails", async () => { + vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); + + const result = await verifyDepositAuthorization( + mockClient, + mockVoucher, + mockDepositAuthorization, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_contract_call_failed_nonces", + payer: buyerAddress, + }); + }); + + it("should return error if deposit authorization nonce is already used", async () => { + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce(BigInt(0)) // permit nonce ok + .mockResolvedValueOnce(true); // deposit authorization nonce already used + + const result = await verifyDepositAuthorization( + mockClient, + mockVoucher, + mockDepositAuthorization, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_nonce_invalid", + payer: buyerAddress, + }); + }); + + it("should return error if deposit authorization nonce check fails", async () => { + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce(BigInt(0)) // permit nonce ok + .mockRejectedValueOnce(new Error("Contract call failed")); + + const result = await verifyDepositAuthorization( + mockClient, + mockVoucher, + mockDepositAuthorization, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: + "invalid_deferred_evm_contract_call_failed_is_deposit_authorization_nonce_used", + payer: buyerAddress, + }); + }); +}); diff --git a/typescript/packages/x402/src/types/verify/constants.ts b/typescript/packages/x402/src/types/verify/constants.ts index 420f823aab..a1a912fc80 100644 --- a/typescript/packages/x402/src/types/verify/constants.ts +++ b/typescript/packages/x402/src/types/verify/constants.ts @@ -4,6 +4,5 @@ export const EvmAddressRegex = /^0x[0-9a-fA-F]{40}$/; export const SvmAddressRegex = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/; export const MixedAddressRegex = /^0x[a-fA-F0-9]{40}|[A-Za-z0-9][A-Za-z0-9-]{0,34}[A-Za-z0-9]$/; export const HexEncoded64ByteRegex = /^0x[0-9a-fA-F]{64}$/; -export const HexEncoded32ByteRegex = /^0x[0-9a-fA-F]{32}$/; export const EvmSignatureRegex = /^0x[0-9a-fA-F]+$/; // Flexible hex signature validation export const EvmTransactionHashRegex = /^0x[0-9a-fA-F]{64}$/; diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index e7cf32a109..9b3c4ac997 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -5,7 +5,6 @@ import { HexEncoded64ByteRegex, EvmMaxAtomicUnits, EvmTransactionHashRegex, - HexEncoded32ByteRegex, } from "../constants"; import { hasMaxLength, isInteger } from "../refiners"; import { BasePaymentPayloadSchema, BasePaymentRequirementsSchema } from "./base"; @@ -53,6 +52,7 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_permit_nonce_invalid", "invalid_deferred_evm_payload_deposit_authorization_nonce_invalid", "invalid_deferred_evm_contract_call_failed_is_deposit_authorization_nonce_used", + "invalid_deferred_evm_payload_deposit_authorization_failed", ] as const; // x402DeferredEvmPayloadVoucher @@ -93,7 +93,7 @@ export const DeferredEscrowDepositAuthorizationPermitSchema = z.object({ owner: z.string().regex(EvmAddressRegex), spender: z.string().regex(EvmAddressRegex), value: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), - nonce: z.string().regex(HexEncoded32ByteRegex), + nonce: z.number().int().nonnegative(), deadline: z.number().int().nonnegative(), domain: z.object({ name: z.string(), @@ -119,7 +119,7 @@ export const DeferredEscrowDepositAuthorizationInnerSchema = z.object({ seller: z.string().regex(EvmAddressRegex), asset: z.string().regex(EvmAddressRegex), amount: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), - nonce: z.string().regex(HexEncoded32ByteRegex), + nonce: z.string().regex(HexEncoded64ByteRegex), expiry: z.number().int().nonnegative(), }); export type DeferredEscrowDepositAuthorizationInner = z.infer< From 87e5645c9d433b46140c383436777cd95ea2f465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 3 Oct 2025 16:00:13 -0300 Subject: [PATCH 090/116] feat(deferred): make permit optional in depositWIthAuth flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../schemes/deferred/evm/facilitator.test.ts | 88 ++++++++++-- .../src/schemes/deferred/evm/facilitator.ts | 82 +++++------ .../src/schemes/deferred/evm/verify.test.ts | 78 +++++++++-- .../x402/src/schemes/deferred/evm/verify.ts | 132 +++++++++++------- .../x402/src/types/verify/schemes/deferred.ts | 6 +- 5 files changed, 275 insertions(+), 111 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts index 82da4ca147..40d44f1c0f 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts @@ -596,7 +596,7 @@ describe("facilitator - depositWithAuthorization", () => { expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, }; - const mockDepositAuthorization = { + const mockDepositAuthorizationWithPermit = { permit: { owner: buyerAddress, spender: escrowAddress, @@ -622,6 +622,19 @@ describe("facilitator - depositWithAuthorization", () => { }, }; + const mockDepositAuthorizationWithoutPermit = { + depositAuthorization: { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "1000000", + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b", + }, + }; + let mockWallet: SignerWallet; beforeEach(() => { @@ -649,11 +662,11 @@ describe("facilitator - depositWithAuthorization", () => { vi.resetAllMocks(); }); - it("should deposit with authorization successfully", async () => { + it("should deposit with authorization successfully with permit", async () => { const result = await depositWithAuthorization( mockWallet, mockVoucher, - mockDepositAuthorization, + mockDepositAuthorizationWithPermit, ); expect(result).toEqual({ @@ -676,7 +689,7 @@ describe("facilitator - depositWithAuthorization", () => { expect(permitCall.args?.[0]).toBe(buyerAddress); expect((permitCall.args?.[1] as Address).toLowerCase()).toBe(escrowAddress.toLowerCase()); expect(permitCall.args?.[2]).toBe(BigInt("1000000")); - expect(permitCall.args?.[3]).toBe(BigInt(mockDepositAuthorization.permit.deadline)); + expect(permitCall.args?.[3]).toBe(BigInt(mockDepositAuthorizationWithPermit.permit.deadline)); // Verify depositWithAuthorization call const depositCall = vi.mocked(mockWallet.writeContract).mock.calls[1][0]; @@ -697,6 +710,41 @@ describe("facilitator - depositWithAuthorization", () => { expect(mockWallet.waitForTransactionReceipt).toHaveBeenCalledTimes(2); }); + it("should deposit with authorization successfully without permit", async () => { + const result = await depositWithAuthorization( + mockWallet, + mockVoucher, + mockDepositAuthorizationWithoutPermit, + ); + + expect(result).toEqual({ + success: true, + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + + // Should have called writeContract only once (depositWithAuthorization, no permit) + expect(mockWallet.writeContract).toHaveBeenCalledTimes(1); + + // Verify depositWithAuthorization call + const depositCall = vi.mocked(mockWallet.writeContract).mock.calls[0][0]; + expect(depositCall).toMatchObject({ + address: escrowAddress, + functionName: "depositWithAuthorization", + chain: mockWallet.chain, + }); + expect(depositCall.args).toHaveLength(2); + expect(depositCall.args?.[0]).toMatchObject({ + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: BigInt("1000000"), + }); + + // Should have waited for only one receipt + expect(mockWallet.waitForTransactionReceipt).toHaveBeenCalledTimes(1); + }); + it("should return error when deposit authorization verification fails", async () => { vi.mocked(verifyModule.verifyDepositAuthorization).mockResolvedValue({ isValid: false, @@ -706,7 +754,7 @@ describe("facilitator - depositWithAuthorization", () => { const result = await depositWithAuthorization( mockWallet, mockVoucher, - mockDepositAuthorization, + mockDepositAuthorizationWithPermit, ); expect(result).toEqual({ @@ -726,7 +774,7 @@ describe("facilitator - depositWithAuthorization", () => { const result = await depositWithAuthorization( mockWallet, mockVoucher, - mockDepositAuthorization, + mockDepositAuthorizationWithPermit, ); expect(result).toEqual({ @@ -748,7 +796,7 @@ describe("facilitator - depositWithAuthorization", () => { const result = await depositWithAuthorization( mockWallet, mockVoucher, - mockDepositAuthorization, + mockDepositAuthorizationWithPermit, ); expect(result).toEqual({ @@ -763,7 +811,7 @@ describe("facilitator - depositWithAuthorization", () => { expect(mockWallet.waitForTransactionReceipt).toHaveBeenCalledTimes(1); }); - it("should return error when depositWithAuthorization transaction fails", async () => { + it("should return error when depositWithAuthorization transaction fails with permit", async () => { mockWallet.writeContract = vi .fn() .mockResolvedValueOnce("0x1234567890abcdef") // permit succeeds @@ -772,7 +820,7 @@ describe("facilitator - depositWithAuthorization", () => { const result = await depositWithAuthorization( mockWallet, mockVoucher, - mockDepositAuthorization, + mockDepositAuthorizationWithPermit, ); expect(result).toEqual({ @@ -786,6 +834,26 @@ describe("facilitator - depositWithAuthorization", () => { expect(mockWallet.writeContract).toHaveBeenCalledTimes(2); }); + it("should return error when depositWithAuthorization transaction fails without permit", async () => { + mockWallet.writeContract = vi.fn().mockRejectedValueOnce(new Error("Deposit failed")); + + const result = await depositWithAuthorization( + mockWallet, + mockVoucher, + mockDepositAuthorizationWithoutPermit, + ); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_transaction_reverted", + transaction: "", + payer: buyerAddress, + }); + + // Should have called writeContract once + expect(mockWallet.writeContract).toHaveBeenCalledTimes(1); + }); + it("should return error when depositWithAuthorization receipt shows failure", async () => { mockWallet.waitForTransactionReceipt = vi .fn() @@ -795,7 +863,7 @@ describe("facilitator - depositWithAuthorization", () => { const result = await depositWithAuthorization( mockWallet, mockVoucher, - mockDepositAuthorization, + mockDepositAuthorizationWithPermit, ); expect(result).toEqual({ diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 7fff421c81..1b605d8871 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -343,55 +343,59 @@ export async function depositWithAuthorization { expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days }; - const mockDepositAuthorization = { + const mockDepositAuthorizationWithPermit = { permit: { owner: buyerAddress, spender: escrowAddress, @@ -1254,6 +1254,19 @@ describe("verifyDepositAuthorization", () => { }, }; + const mockDepositAuthorizationWithoutPermit = { + depositAuthorization: { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "1000000", + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" as `0x${string}`, + }, + }; + let mockClient: ConnectedClient; beforeEach(() => { @@ -1271,7 +1284,7 @@ describe("verifyDepositAuthorization", () => { vi.resetAllMocks(); }); - it("should return valid if deposit authorization is valid", async () => { + it("should return valid if deposit authorization is valid with permit", async () => { vi.mocked(mockClient.readContract) .mockResolvedValueOnce(BigInt(0)) // permit nonce .mockResolvedValueOnce(false); // deposit authorization nonce not used @@ -1279,16 +1292,29 @@ describe("verifyDepositAuthorization", () => { const result = await verifyDepositAuthorization( mockClient, mockVoucher, - mockDepositAuthorization, + mockDepositAuthorizationWithPermit, + ); + expect(result).toEqual({ isValid: true }); + }); + + it("should return valid if deposit authorization is valid without permit", async () => { + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce(BigInt(2000000)) // allowance (sufficient) + .mockResolvedValueOnce(false); // deposit authorization nonce not used + + const result = await verifyDepositAuthorization( + mockClient, + mockVoucher, + mockDepositAuthorizationWithoutPermit, ); expect(result).toEqual({ isValid: true }); }); it("should return error if permit signature is invalid", async () => { const invalidPermit = { - ...mockDepositAuthorization, + ...mockDepositAuthorizationWithPermit, permit: { - ...mockDepositAuthorization.permit, + ...mockDepositAuthorizationWithPermit.permit!, signature: "0x999b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c" as `0x${string}`, }, @@ -1304,9 +1330,9 @@ describe("verifyDepositAuthorization", () => { it("should return error if deposit authorization signature is invalid", async () => { const invalidDepositAuth = { - ...mockDepositAuthorization, + ...mockDepositAuthorizationWithPermit, depositAuthorization: { - ...mockDepositAuthorization.depositAuthorization, + ...mockDepositAuthorizationWithPermit.depositAuthorization, signature: "0x999b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c" as `0x${string}`, }, @@ -1320,13 +1346,43 @@ describe("verifyDepositAuthorization", () => { }); }); + it("should return error if allowance is insufficient when no permit", async () => { + vi.mocked(mockClient.readContract).mockResolvedValueOnce(BigInt(500000)); // allowance too low + + const result = await verifyDepositAuthorization( + mockClient, + mockVoucher, + mockDepositAuthorizationWithoutPermit, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_insufficient_allowance", + payer: buyerAddress, + }); + }); + + it("should return error if allowance check fails when no permit", async () => { + vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); + + const result = await verifyDepositAuthorization( + mockClient, + mockVoucher, + mockDepositAuthorizationWithoutPermit, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_contract_call_failed_allowance", + payer: buyerAddress, + }); + }); + it("should return error if permit nonce is invalid", async () => { vi.mocked(mockClient.readContract).mockResolvedValueOnce(BigInt(5)); // Different nonce const result = await verifyDepositAuthorization( mockClient, mockVoucher, - mockDepositAuthorization, + mockDepositAuthorizationWithPermit, ); expect(result).toEqual({ isValid: false, @@ -1341,7 +1397,7 @@ describe("verifyDepositAuthorization", () => { const result = await verifyDepositAuthorization( mockClient, mockVoucher, - mockDepositAuthorization, + mockDepositAuthorizationWithPermit, ); expect(result).toEqual({ isValid: false, @@ -1358,7 +1414,7 @@ describe("verifyDepositAuthorization", () => { const result = await verifyDepositAuthorization( mockClient, mockVoucher, - mockDepositAuthorization, + mockDepositAuthorizationWithPermit, ); expect(result).toEqual({ isValid: false, @@ -1375,7 +1431,7 @@ describe("verifyDepositAuthorization", () => { const result = await verifyDepositAuthorization( mockClient, mockVoucher, - mockDepositAuthorization, + mockDepositAuthorizationWithPermit, ); expect(result).toEqual({ isValid: false, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index df0364ccc7..86d89973d5 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -487,35 +487,38 @@ export async function verifyDepositAuthorization< ): Promise { const { permit, depositAuthorization: depositAuthorizationInner } = depositAuthorization; + const DATE_NOW = Math.floor(Date.now() / 1000); + const DATE_ONE_WEEK = 604800; + // Verify the permit signature - const isPermitValid = await verifyPermit( - permit, - permit.signature as Hex, - permit.owner as Address, - voucher.chainId, - voucher.asset as Address, // This ensures the permit is for the voucher's asset - ); - if (!isPermitValid) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_permit_signature", - payer: permit.owner, - }; - } + if (permit) { + const isPermitValid = await verifyPermit( + permit, + permit.signature as Hex, + permit.owner as Address, + voucher.chainId, + voucher.asset as Address, // This ensures the permit is for the voucher's asset + ); + if (!isPermitValid) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_permit_signature", + payer: permit.owner, + }; + } - // Verify permit continuity - const now = Math.floor(Date.now() / 1000); - const oneWeek = 604800; - if ( - getAddress(permit.owner) !== getAddress(voucher.buyer) || - getAddress(permit.spender) !== getAddress(voucher.escrow) || - permit.deadline < now + oneWeek - ) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_permit_continuity", - payer: permit.owner, - }; + // Verify permit continuity + if ( + getAddress(permit.owner) !== getAddress(voucher.buyer) || + getAddress(permit.spender) !== getAddress(voucher.escrow) || + permit.deadline < DATE_NOW + DATE_ONE_WEEK + ) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_permit_continuity", + payer: permit.owner, + }; + } } // Verify deposit authorization signature @@ -539,7 +542,7 @@ export async function verifyDepositAuthorization< getAddress(depositAuthorizationInner.buyer) !== getAddress(voucher.buyer) || getAddress(depositAuthorizationInner.seller) !== getAddress(voucher.seller) || getAddress(depositAuthorizationInner.asset) !== getAddress(voucher.asset) || - depositAuthorizationInner.expiry < now + oneWeek + depositAuthorizationInner.expiry < DATE_NOW + DATE_ONE_WEEK ) { return { isValid: false, @@ -548,39 +551,70 @@ export async function verifyDepositAuthorization< }; } - // Very permit / deposit authorization continuity - if ( - getAddress(depositAuthorizationInner.buyer) !== getAddress(permit.owner) || - BigInt(depositAuthorizationInner.amount) > BigInt(permit.value) - ) { + // Verify permit owner matches the deposit authorization buyer + if (permit) { + if (getAddress(depositAuthorizationInner.buyer) !== getAddress(permit.owner)) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_buyer_mismatch", + payer: depositAuthorizationInner.buyer, + }; + } + } + + // Verify escrow can pull from the buyer's account based on their allowance (or permit) + // Consider current allowance if there is no permit + let allowance = 0n; + if (!permit) { + try { + allowance = await client.readContract({ + address: voucher.asset as Address, + abi: usdcABI, + functionName: "allowance", + args: [voucher.buyer as Address, voucher.escrow as Address], + }); + } catch { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_contract_call_failed_allowance", + payer: voucher.buyer, + }; + } + } else { + allowance = BigInt(permit.value); + } + + if (BigInt(depositAuthorizationInner.amount) > allowance) { return { isValid: false, - invalidReason: "invalid_deferred_evm_payload_deposit_authorization_cross_continuity", + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_insufficient_allowance", payer: depositAuthorizationInner.buyer, }; } // Verify permit nonce - try { - const permitNonce = await client.readContract({ - address: voucher.asset as Address, - abi: usdcABI, - functionName: "nonces", - args: [voucher.buyer as Address], - }); - if (permitNonce !== BigInt(permit.nonce)) { + if (permit) { + try { + const permitNonce = await client.readContract({ + address: voucher.asset as Address, + abi: usdcABI, + functionName: "nonces", + args: [voucher.buyer as Address], + }); + if (permitNonce !== BigInt(permit.nonce)) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_permit_nonce_invalid", + payer: voucher.buyer, + }; + } + } catch { return { isValid: false, - invalidReason: "invalid_deferred_evm_payload_permit_nonce_invalid", + invalidReason: "invalid_deferred_evm_contract_call_failed_nonces", payer: voucher.buyer, }; } - } catch { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_nonces", - payer: voucher.buyer, - }; } // Verify deposit authorization nonce diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 9b3c4ac997..5ce455e71a 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -47,12 +47,14 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_deposit_authorization_signature", "invalid_deferred_evm_payload_permit_continuity", "invalid_deferred_evm_payload_deposit_authorization_continuity", - "invalid_deferred_evm_payload_deposit_authorization_cross_continuity", "invalid_deferred_evm_contract_call_failed_nonces", "invalid_deferred_evm_payload_permit_nonce_invalid", "invalid_deferred_evm_payload_deposit_authorization_nonce_invalid", "invalid_deferred_evm_contract_call_failed_is_deposit_authorization_nonce_used", "invalid_deferred_evm_payload_deposit_authorization_failed", + "invalid_deferred_evm_payload_deposit_authorization_buyer_mismatch", + "invalid_deferred_evm_contract_call_failed_allowance", + "invalid_deferred_evm_payload_deposit_authorization_insufficient_allowance", ] as const; // x402DeferredEvmPayloadVoucher @@ -137,7 +139,7 @@ export type DeferredEscrowDepositAuthorizationSignedInner = z.infer< // x402DeferredEscrowDepositAuthorization export const DeferredEscrowDepositAuthorizationSchema = z.object({ - permit: DeferredEscrowDepositAuthorizationSignedPermitSchema, + permit: DeferredEscrowDepositAuthorizationSignedPermitSchema.optional(), depositAuthorization: DeferredEscrowDepositAuthorizationSignedInnerSchema, }); export type DeferredEscrowDepositAuthorization = z.infer< From 518168c19f299dc032a940a50318b71dea374e01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 10 Oct 2025 19:05:52 -0300 Subject: [PATCH 091/116] wip(deferred): implement depositwithauth flow changes for components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- solidity/deferred-escrow/addresses.json | 4 +- .../src/DeferredPaymentEscrow.sol | 1374 +++++++++-------- .../src/IDeferredPaymentEscrow.sol | 971 ++++++------ typescript/packages/x402-axios/src/index.ts | 1 + typescript/packages/x402-express/src/index.ts | 6 +- .../x402/src/client/createPaymentHeader.ts | 4 +- .../src/schemes/deferred/evm/client.test.ts | 85 + .../x402/src/schemes/deferred/evm/client.ts | 21 +- .../src/schemes/deferred/evm/facilitator.ts | 64 + .../x402/src/schemes/deferred/evm/server.ts | 22 + .../src/schemes/deferred/evm/store.mock.ts | 11 +- .../x402/src/schemes/deferred/evm/store.ts | 6 + .../deferred/evm/utils/paymentUtils.test.ts | 106 ++ .../deferred/evm/utils/paymentUtils.ts | 8 +- .../x402/src/schemes/deferred/evm/verify.ts | 7 +- .../src/types/shared/evm/deferredEscrowABI.ts | 13 + .../x402/src/types/verify/schemes/deferred.ts | 11 + .../packages/x402/src/verify/useDeferred.ts | 28 + 18 files changed, 1597 insertions(+), 1145 deletions(-) diff --git a/solidity/deferred-escrow/addresses.json b/solidity/deferred-escrow/addresses.json index ad86e6f22a..5a8cfcb425 100644 --- a/solidity/deferred-escrow/addresses.json +++ b/solidity/deferred-escrow/addresses.json @@ -1,5 +1,5 @@ { "84532": { - "deferredPaymentEscrow": "0xF1308b39EdB10E5163581C1f8D0Bf8E26404A11f" + "deferredPaymentEscrow": "0x32f493421eb3e296a2c66505a6ebd1540943a2ac" } -} +} \ No newline at end of file diff --git a/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol b/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol index 505087913b..97c1ed9411 100644 --- a/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol +++ b/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.30; -import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; -import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import {IDeferredPaymentEscrow} from "./IDeferredPaymentEscrow.sol"; -import {EscrowSignatureLib} from "./libraries/EscrowSignatureLib.sol"; +import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; +import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { IDeferredPaymentEscrow } from "./IDeferredPaymentEscrow.sol"; +import { EscrowSignatureLib } from "./libraries/EscrowSignatureLib.sol"; /** * @title DeferredPaymentEscrow @@ -15,699 +15,735 @@ import {EscrowSignatureLib} from "./libraries/EscrowSignatureLib.sol"; * @dev Implements EIP-712 signed vouchers with ERC-1271 smart account support */ contract DeferredPaymentEscrow is ReentrancyGuard, EIP712, IDeferredPaymentEscrow { - using SafeERC20 for IERC20; - using EnumerableSet for EnumerableSet.Bytes32Set; - - /// @notice Maximum allowed thawing period (30 days) - uint256 public constant MAX_THAWING_PERIOD = 30 days; - - /// @notice Immutable thawing period for withdrawals - uint256 public immutable THAWING_PERIOD; - - /// @notice EIP-712 type hash for voucher structure - bytes32 public constant VOUCHER_TYPEHASH = EscrowSignatureLib.VOUCHER_TYPEHASH; - - /// @notice EIP-712 type hash for deposit authorization structure - bytes32 public constant DEPOSIT_AUTHORIZATION_TYPEHASH = EscrowSignatureLib.DEPOSIT_AUTHORIZATION_TYPEHASH; - - /// @notice EIP-712 type hash for flush authorization structure - bytes32 public constant FLUSH_AUTHORIZATION_TYPEHASH = EscrowSignatureLib.FLUSH_AUTHORIZATION_TYPEHASH; - - /// @notice EIP-712 type hash for flush all authorization structure - bytes32 public constant FLUSH_ALL_AUTHORIZATION_TYPEHASH = EscrowSignatureLib.FLUSH_ALL_AUTHORIZATION_TYPEHASH; - - /// @notice Struct to store seller and asset information for escrow keys - struct EscrowKey { - address seller; - address asset; - } - - /// @custom:storage-location erc7201:deferred.payment.escrow.main - struct MainStorage { - /// @notice Triple-nested mapping: buyer => seller => asset => EscrowAccount - mapping( - address buyer => mapping(address seller => mapping(address asset => IDeferredPaymentEscrow.EscrowAccount)) - ) accounts; - /// @notice Quadruple-nested mapping: buyer => seller => asset => voucherId => collected amount - mapping( - address buyer => mapping(address seller => mapping(address asset => mapping(bytes32 voucherId => uint256))) - ) voucherCollected; - /// @notice Set of hashed (seller, asset) pairs per buyer for account tracking - mapping(address buyer => EnumerableSet.Bytes32Set) buyerEscrowKeys; - /// @notice Decode hash back to (seller, asset) - mapping(bytes32 keyHash => EscrowKey) escrowKeyToInfo; - /// @notice Track used deposit authorization nonces by buyer and nonce - mapping(address buyer => mapping(bytes32 nonce => bool)) usedDepositNonces; - /// @notice Track used flush authorization nonces by buyer and nonce - mapping(address buyer => mapping(bytes32 nonce => bool)) usedFlushNonces; - /// @notice Track used flush all authorization nonces by buyer and nonce - mapping(address buyer => mapping(bytes32 nonce => bool)) usedFlushAllNonces; - } - - // keccak256(abi.encode(uint256(keccak256("deferred.payment.escrow.main")) - 1)) & ~bytes32(uint256(0xff)) - bytes32 constant MAIN_STORAGE_LOCATION = 0x4cf6ea8df9d6256fc1076c222eae360b1d94159d5580e17aba1e651f33b72300; - - function _getMainStorage() private pure returns (MainStorage storage $) { - assembly { - $.slot := MAIN_STORAGE_LOCATION - } - } - - /** - * @notice Constructor - * @param _thawingPeriod Thawing period in seconds - */ - constructor(uint256 _thawingPeriod) EIP712("DeferredPaymentEscrow", "1") { - require(_thawingPeriod <= MAX_THAWING_PERIOD, InvalidThawingPeriod(_thawingPeriod, MAX_THAWING_PERIOD)); - - THAWING_PERIOD = _thawingPeriod; - } - - /** - * @notice Deposit tokens into escrow for a specific seller and asset - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount to deposit - */ - function deposit(address seller, address asset, uint256 amount) external nonReentrant { - _deposit(msg.sender, seller, asset, amount, msg.sender); - } - - /** - * @notice Deposit tokens into escrow on behalf of a buyer - * @param buyer Address of the buyer who will own the escrow - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount to deposit - */ - function depositTo(address buyer, address seller, address asset, uint256 amount) external nonReentrant { - require(buyer != address(0), InvalidAddress(buyer)); - _deposit(buyer, seller, asset, amount, msg.sender); - } - - /** - * @notice Deposit tokens for multiple sellers with a single asset in a single transaction - * @param asset ERC-20 token address - * @param deposits Array of deposit inputs - */ - function depositMany(address asset, DepositInput[] calldata deposits) external nonReentrant { - require(asset != address(0), InvalidAsset(asset)); - require(deposits.length != 0, NoDepositsProvided()); - - MainStorage storage $ = _getMainStorage(); - uint256 totalAmount = 0; - - // Single loop: validate inputs, calculate total, and update balances - for (uint256 i = 0; i < deposits.length; i++) { - DepositInput calldata depositInput = deposits[i]; - require(depositInput.seller != address(0), InvalidAddress(depositInput.seller)); - require(depositInput.amount != 0, InvalidAmount(depositInput.amount)); - - totalAmount += depositInput.amount; - - // Update account balance - EscrowAccount storage account = $.accounts[msg.sender][depositInput.seller][asset]; - account.balance += depositInput.amount; - - // Track account in buyerEscrowKeys set - bytes32 key = keccak256(abi.encodePacked(depositInput.seller, asset)); - if ($.buyerEscrowKeys[msg.sender].add(key)) { - $.escrowKeyToInfo[key] = EscrowKey(depositInput.seller, asset); - } - - emit Deposited(msg.sender, depositInput.seller, asset, depositInput.amount, account.balance); - } - - // Single token transfer for all deposits - IERC20(asset).safeTransferFrom(msg.sender, address(this), totalAmount); - } - - /** - * @notice Deposit tokens using EIP-712 signed authorization - * @param auth The deposit authorization struct - * @param signature Buyer's signature for the authorization - */ - function depositWithAuthorization(DepositAuthorization calldata auth, bytes calldata signature) - external - nonReentrant - { - // Check expiry - require(block.timestamp <= auth.expiry, AuthorizationExpired(auth.expiry, block.timestamp)); - - // Check and mark nonce as used - MainStorage storage $ = _getMainStorage(); - require(!$.usedDepositNonces[auth.buyer][auth.nonce], NonceAlreadyUsed(auth.nonce)); - $.usedDepositNonces[auth.buyer][auth.nonce] = true; - - // Validate signature - require( - EscrowSignatureLib.isDepositAuthorizationValid(auth, signature, _domainSeparatorV4()), - InvalidAuthorization() - ); - - // Use internal _deposit function for consistency - _deposit(auth.buyer, auth.seller, auth.asset, auth.amount, auth.buyer); - - // Emit authorization-specific event - emit DepositAuthorized(auth.buyer, auth.seller, auth.asset, auth.amount, auth.nonce); + using SafeERC20 for IERC20; + using EnumerableSet for EnumerableSet.Bytes32Set; + + /// @notice Maximum allowed thawing period (30 days) + uint256 public constant MAX_THAWING_PERIOD = 30 days; + + /// @notice Immutable thawing period for withdrawals + uint256 public immutable THAWING_PERIOD; + + /// @notice EIP-712 type hash for voucher structure + bytes32 public constant VOUCHER_TYPEHASH = EscrowSignatureLib.VOUCHER_TYPEHASH; + + /// @notice EIP-712 type hash for deposit authorization structure + bytes32 public constant DEPOSIT_AUTHORIZATION_TYPEHASH = EscrowSignatureLib.DEPOSIT_AUTHORIZATION_TYPEHASH; + + /// @notice EIP-712 type hash for flush authorization structure + bytes32 public constant FLUSH_AUTHORIZATION_TYPEHASH = EscrowSignatureLib.FLUSH_AUTHORIZATION_TYPEHASH; + + /// @notice EIP-712 type hash for flush all authorization structure + bytes32 public constant FLUSH_ALL_AUTHORIZATION_TYPEHASH = EscrowSignatureLib.FLUSH_ALL_AUTHORIZATION_TYPEHASH; + + /// @notice Struct to store seller and asset information for escrow keys + struct EscrowKey { + address seller; + address asset; + } + + /// @custom:storage-location erc7201:deferred.payment.escrow.main + struct MainStorage { + /// @notice Triple-nested mapping: buyer => seller => asset => EscrowAccount + mapping(address buyer => mapping(address seller => mapping(address asset => IDeferredPaymentEscrow.EscrowAccount))) accounts; + /// @notice Quadruple-nested mapping: buyer => seller => asset => voucherId => collected amount + mapping(address buyer => mapping(address seller => mapping(address asset => mapping(bytes32 voucherId => uint256)))) voucherCollected; + /// @notice Set of hashed (seller, asset) pairs per buyer for account tracking + mapping(address buyer => EnumerableSet.Bytes32Set) buyerEscrowKeys; + /// @notice Decode hash back to (seller, asset) + mapping(bytes32 keyHash => EscrowKey) escrowKeyToInfo; + /// @notice Track used deposit authorization nonces by buyer and nonce + mapping(address buyer => mapping(bytes32 nonce => bool)) usedDepositNonces; + /// @notice Track used flush authorization nonces by buyer and nonce + mapping(address buyer => mapping(bytes32 nonce => bool)) usedFlushNonces; + /// @notice Track used flush all authorization nonces by buyer and nonce + mapping(address buyer => mapping(bytes32 nonce => bool)) usedFlushAllNonces; + } + + // keccak256(abi.encode(uint256(keccak256("deferred.payment.escrow.main")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 constant MAIN_STORAGE_LOCATION = 0x4cf6ea8df9d6256fc1076c222eae360b1d94159d5580e17aba1e651f33b72300; + + function _getMainStorage() private pure returns (MainStorage storage $) { + assembly { + $.slot := MAIN_STORAGE_LOCATION } - - /** - * @notice Initiate or increase withdrawal thawing amount (starts/resets thawing period) - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount to add to thawing - */ - function thaw(address seller, address asset, uint256 amount) external { - require(seller != address(0), InvalidAddress(seller)); - require(asset != address(0), InvalidAsset(asset)); - require(amount != 0, InvalidAmount(amount)); - - MainStorage storage $ = _getMainStorage(); - IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[msg.sender][seller][asset]; - - // Check if the requested thaw amount can be accommodated - uint256 newThawingAmount = account.thawingAmount + amount; - require(account.balance >= newThawingAmount, InsufficientBalance(account.balance, newThawingAmount)); - - _thaw(msg.sender, seller, asset, amount); + } + + /** + * @notice Constructor + * @param _thawingPeriod Thawing period in seconds + */ + constructor(uint256 _thawingPeriod) EIP712("DeferredPaymentEscrow", "1") { + require(_thawingPeriod <= MAX_THAWING_PERIOD, InvalidThawingPeriod(_thawingPeriod, MAX_THAWING_PERIOD)); + + THAWING_PERIOD = _thawingPeriod; + } + + /** + * @notice Deposit tokens into escrow for a specific seller and asset + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + */ + function deposit(address seller, address asset, uint256 amount) external nonReentrant { + _deposit(msg.sender, seller, asset, amount, msg.sender); + } + + /** + * @notice Deposit tokens into escrow on behalf of a buyer + * @param buyer Address of the buyer who will own the escrow + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + */ + function depositTo(address buyer, address seller, address asset, uint256 amount) external nonReentrant { + require(buyer != address(0), InvalidAddress(buyer)); + _deposit(buyer, seller, asset, amount, msg.sender); + } + + /** + * @notice Deposit tokens for multiple sellers with a single asset in a single transaction + * @param asset ERC-20 token address + * @param deposits Array of deposit inputs + */ + function depositMany(address asset, DepositInput[] calldata deposits) external nonReentrant { + require(asset != address(0), InvalidAsset(asset)); + require(deposits.length != 0, NoDepositsProvided()); + + MainStorage storage $ = _getMainStorage(); + uint256 totalAmount = 0; + + // Single loop: validate inputs, calculate total, and update balances + for (uint256 i = 0; i < deposits.length; i++) { + DepositInput calldata depositInput = deposits[i]; + require(depositInput.seller != address(0), InvalidAddress(depositInput.seller)); + require(depositInput.amount != 0, InvalidAmount(depositInput.amount)); + + totalAmount += depositInput.amount; + + // Update account balance + EscrowAccount storage account = $.accounts[msg.sender][depositInput.seller][asset]; + account.balance += depositInput.amount; + + // Track account in buyerEscrowKeys set + bytes32 key = keccak256(abi.encodePacked(depositInput.seller, asset)); + if ($.buyerEscrowKeys[msg.sender].add(key)) { + $.escrowKeyToInfo[key] = EscrowKey(depositInput.seller, asset); + } + + emit Deposited(msg.sender, depositInput.seller, asset, depositInput.amount, account.balance); } - /** - * @notice Cancel an ongoing thawing process - * @param seller Address of the seller - * @param asset ERC-20 token address - */ - function cancelThaw(address seller, address asset) external { - require(seller != address(0), InvalidAddress(seller)); - require(asset != address(0), InvalidAsset(asset)); - - MainStorage storage $ = _getMainStorage(); - IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[msg.sender][seller][asset]; - require(account.thawingAmount != 0, NoThawingInProgress(msg.sender, seller, asset)); - - uint256 thawingAmount = account.thawingAmount; - - // Cancel thawing (no balance change needed) - account.thawingAmount = 0; - account.thawEndTime = 0; - - emit ThawCancelled(msg.sender, seller, asset, thawingAmount); + // Single token transfer for all deposits + IERC20(asset).safeTransferFrom(msg.sender, address(this), totalAmount); + } + + /** + * @notice Deposit tokens using EIP-712 signed authorization + * @param auth The deposit authorization struct + * @param signature Buyer's signature for the authorization + */ + function depositWithAuthorization( + DepositAuthorization calldata auth, + bytes calldata signature + ) external nonReentrant { + // Check expiry + require(block.timestamp <= auth.expiry, AuthorizationExpired(auth.expiry, block.timestamp)); + + // Check and mark nonce as used + MainStorage storage $ = _getMainStorage(); + require(!$.usedDepositNonces[auth.buyer][auth.nonce], NonceAlreadyUsed(auth.nonce)); + $.usedDepositNonces[auth.buyer][auth.nonce] = true; + + // Validate signature + require( + EscrowSignatureLib.isDepositAuthorizationValid(auth, signature, _domainSeparatorV4()), + InvalidAuthorization() + ); + + // Use internal _deposit function for consistency + _deposit(auth.buyer, auth.seller, auth.asset, auth.amount, auth.buyer); + + // Emit authorization-specific event + emit DepositAuthorized(auth.buyer, auth.seller, auth.asset, auth.amount, auth.nonce); + } + + /** + * @notice Initiate or increase withdrawal thawing amount (starts/resets thawing period) + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to add to thawing + */ + function thaw(address seller, address asset, uint256 amount) external { + require(seller != address(0), InvalidAddress(seller)); + require(asset != address(0), InvalidAsset(asset)); + require(amount != 0, InvalidAmount(amount)); + + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[msg.sender][seller][asset]; + + // Check if the requested thaw amount can be accommodated + uint256 newThawingAmount = account.thawingAmount + amount; + require(account.balance >= newThawingAmount, InsufficientBalance(account.balance, newThawingAmount)); + + _thaw(msg.sender, seller, asset, amount); + } + + /** + * @notice Cancel an ongoing thawing process + * @param seller Address of the seller + * @param asset ERC-20 token address + */ + function cancelThaw(address seller, address asset) external { + require(seller != address(0), InvalidAddress(seller)); + require(asset != address(0), InvalidAsset(asset)); + + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[msg.sender][seller][asset]; + require(account.thawingAmount != 0, NoThawingInProgress(msg.sender, seller, asset)); + + uint256 thawingAmount = account.thawingAmount; + + // Cancel thawing (no balance change needed) + account.thawingAmount = 0; + account.thawEndTime = 0; + + emit ThawCancelled(msg.sender, seller, asset, thawingAmount); + } + + /** + * @notice Complete withdrawal after thawing period + * @param seller Address of the seller + * @param asset ERC-20 token address + */ + function withdraw(address seller, address asset) external nonReentrant { + require(seller != address(0), InvalidAddress(seller)); + require(asset != address(0), InvalidAsset(asset)); + + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[msg.sender][seller][asset]; + + // Check if there's thawing in progress + require(account.thawingAmount > 0, NoThawingInProgress(msg.sender, seller, asset)); + + // Check if thawing period is complete + require(block.timestamp >= account.thawEndTime, ThawingPeriodNotCompleted(block.timestamp, account.thawEndTime)); + + // Perform the withdrawal + _withdraw(msg.sender, seller, asset); + } + + /** + * @notice Initiate or complete flush using EIP-712 signed authorization + * @dev "Flush" performs two operations on a specific escrow account: + * 1. Withdraws any funds that have completed their thawing period (ready to withdraw) + * 2. Initiates thawing for any remaining balance that isn't already thawing + * This allows a Facilitator to help a buyer recover their funds with just a signature. + * @param auth The flush authorization struct containing buyer, seller, asset, nonce, and expiry + * @param signature Buyer's signature for the authorization + */ + function flushWithAuthorization(FlushAuthorization calldata auth, bytes calldata signature) external nonReentrant { + // Check expiry + require(block.timestamp <= auth.expiry, AuthorizationExpired(auth.expiry, block.timestamp)); + + // Check and mark nonce as used + MainStorage storage $ = _getMainStorage(); + require(!$.usedFlushNonces[auth.buyer][auth.nonce], NonceAlreadyUsed(auth.nonce)); + $.usedFlushNonces[auth.buyer][auth.nonce] = true; + + // Validate signature + require( + EscrowSignatureLib.isFlushAuthorizationValid(auth, signature, _domainSeparatorV4()), + InvalidAuthorization() + ); + + // First, withdraw any funds that are ready + _withdraw(auth.buyer, auth.seller, auth.asset); + + // Then, calculate and thaw any remaining balance that isn't already thawing + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[auth.buyer][auth.seller][auth.asset]; + uint256 availableToThaw = account.balance > account.thawingAmount ? account.balance - account.thawingAmount : 0; + + uint256 thawedAmount = 0; + if (availableToThaw > 0) { + thawedAmount = _thaw(auth.buyer, auth.seller, auth.asset, availableToThaw); } - /** - * @notice Complete withdrawal after thawing period - * @param seller Address of the seller - * @param asset ERC-20 token address - */ - function withdraw(address seller, address asset) external nonReentrant { - require(seller != address(0), InvalidAddress(seller)); - require(asset != address(0), InvalidAsset(asset)); - - MainStorage storage $ = _getMainStorage(); - IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[msg.sender][seller][asset]; - - // Check if there's thawing in progress - require(account.thawingAmount > 0, NoThawingInProgress(msg.sender, seller, asset)); - - // Check if thawing period is complete - require(block.timestamp >= account.thawEndTime, ThawingPeriodNotCompleted(block.timestamp, account.thawEndTime)); - - // Perform the withdrawal - _withdraw(msg.sender, seller, asset); + // Emit the flush event (even if nothing happened - idempotent operation) + emit FlushAuthorized(auth.buyer, auth.seller, auth.asset, auth.nonce, thawedAmount > 0); + } + + /** + * @notice Flush all escrows for a buyer using EIP-712 signed authorization + * @dev "Flush all" performs a flush operation on ALL of a buyer's escrow accounts: + * For each account: + * 1. Withdraws any funds that have completed their thawing period (ready to withdraw) + * 2. Initiates thawing for any remaining balance that isn't already thawing + * This allows a Facilitator to help a buyer recover all their escrowed funds across + * all sellers and assets with just a single signature. + * @param auth The flush all authorization struct containing buyer, nonce, and expiry + * @param signature Buyer's signature for the authorization + */ + function flushAllWithAuthorization( + FlushAllAuthorization calldata auth, + bytes calldata signature + ) external nonReentrant { + // Check expiry + require(block.timestamp <= auth.expiry, AuthorizationExpired(auth.expiry, block.timestamp)); + + // Check and mark nonce as used + MainStorage storage $ = _getMainStorage(); + require(!$.usedFlushAllNonces[auth.buyer][auth.nonce], NonceAlreadyUsed(auth.nonce)); + $.usedFlushAllNonces[auth.buyer][auth.nonce] = true; + + // Validate signature + require( + EscrowSignatureLib.isFlushAllAuthorizationValid(auth, signature, _domainSeparatorV4()), + InvalidAuthorization() + ); + + uint256 accountsFlushed = 0; + + // Get all escrow keys for this buyer + EnumerableSet.Bytes32Set storage escrowKeys = $.buyerEscrowKeys[auth.buyer]; + uint256 keysLength = escrowKeys.length(); + + // Process each account: withdraw ready funds AND thaw remaining balance + // Iterate backwards to handle removals safely + for (uint256 i = keysLength; i > 0; i--) { + bytes32 escrowKey = escrowKeys.at(i - 1); + EscrowKey storage keyInfo = $.escrowKeyToInfo[escrowKey]; + + // First, withdraw any funds that are ready + uint256 withdrawnAmount = _withdraw(auth.buyer, keyInfo.seller, keyInfo.asset); + + // Then, calculate and thaw any remaining balance that isn't already thawing + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[auth.buyer][keyInfo.seller][keyInfo.asset]; + uint256 availableToThaw = account.balance > account.thawingAmount ? account.balance - account.thawingAmount : 0; + + uint256 thawedAmount = 0; + if (availableToThaw > 0) { + thawedAmount = _thaw(auth.buyer, keyInfo.seller, keyInfo.asset, availableToThaw); + } + + // Count accounts that had activity + if (withdrawnAmount > 0 || thawedAmount > 0) { + accountsFlushed++; + } } - /** - * @notice Initiate or complete flush using EIP-712 signed authorization - * @dev "Flush" performs two operations on a specific escrow account: - * 1. Withdraws any funds that have completed their thawing period (ready to withdraw) - * 2. Initiates thawing for any remaining balance that isn't already thawing - * This allows a Facilitator to help a buyer recover their funds with just a signature. - * @param auth The flush authorization struct containing buyer, seller, asset, nonce, and expiry - * @param signature Buyer's signature for the authorization - */ - function flushWithAuthorization(FlushAuthorization calldata auth, bytes calldata signature) external nonReentrant { - // Check expiry - require(block.timestamp <= auth.expiry, AuthorizationExpired(auth.expiry, block.timestamp)); - - // Check and mark nonce as used - MainStorage storage $ = _getMainStorage(); - require(!$.usedFlushNonces[auth.buyer][auth.nonce], NonceAlreadyUsed(auth.nonce)); - $.usedFlushNonces[auth.buyer][auth.nonce] = true; - - // Validate signature - require( - EscrowSignatureLib.isFlushAuthorizationValid(auth, signature, _domainSeparatorV4()), InvalidAuthorization() - ); - - // First, withdraw any funds that are ready - _withdraw(auth.buyer, auth.seller, auth.asset); - - // Then, calculate and thaw any remaining balance that isn't already thawing - IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[auth.buyer][auth.seller][auth.asset]; - uint256 availableToThaw = account.balance > account.thawingAmount ? account.balance - account.thawingAmount : 0; - - uint256 thawedAmount = 0; - if (availableToThaw > 0) { - thawedAmount = _thaw(auth.buyer, auth.seller, auth.asset, availableToThaw); - } - - // Emit the flush event (even if nothing happened - idempotent operation) - emit FlushAuthorized(auth.buyer, auth.seller, auth.asset, auth.nonce, thawedAmount > 0); + emit FlushAllAuthorized(auth.buyer, auth.nonce, accountsFlushed); + } + + /** + * @notice Collect a single voucher + * @param voucher The voucher to collect + * @param signature Buyer's signature for the voucher + */ + function collect(Voucher calldata voucher, bytes calldata signature) external nonReentrant { + _collectVoucher(voucher, signature); + } + + /** + * @notice Collect multiple vouchers in a single transaction + * @param vouchers Array of signed vouchers + */ + function collectMany(SignedVoucher[] calldata vouchers) external nonReentrant { + require(vouchers.length != 0, NoVouchersProvided()); + + for (uint256 i = 0; i < vouchers.length; i++) { + _collectVoucher(vouchers[i].voucher, vouchers[i].signature); } - - /** - * @notice Flush all escrows for a buyer using EIP-712 signed authorization - * @dev "Flush all" performs a flush operation on ALL of a buyer's escrow accounts: - * For each account: - * 1. Withdraws any funds that have completed their thawing period (ready to withdraw) - * 2. Initiates thawing for any remaining balance that isn't already thawing - * This allows a Facilitator to help a buyer recover all their escrowed funds across - * all sellers and assets with just a single signature. - * @param auth The flush all authorization struct containing buyer, nonce, and expiry - * @param signature Buyer's signature for the authorization - */ - function flushAllWithAuthorization(FlushAllAuthorization calldata auth, bytes calldata signature) - external - nonReentrant - { - // Check expiry - require(block.timestamp <= auth.expiry, AuthorizationExpired(auth.expiry, block.timestamp)); - - // Check and mark nonce as used - MainStorage storage $ = _getMainStorage(); - require(!$.usedFlushAllNonces[auth.buyer][auth.nonce], NonceAlreadyUsed(auth.nonce)); - $.usedFlushAllNonces[auth.buyer][auth.nonce] = true; - - // Validate signature - require( - EscrowSignatureLib.isFlushAllAuthorizationValid(auth, signature, _domainSeparatorV4()), - InvalidAuthorization() - ); - - uint256 accountsFlushed = 0; - - // Get all escrow keys for this buyer - EnumerableSet.Bytes32Set storage escrowKeys = $.buyerEscrowKeys[auth.buyer]; - uint256 keysLength = escrowKeys.length(); - - // Process each account: withdraw ready funds AND thaw remaining balance - // Iterate backwards to handle removals safely - for (uint256 i = keysLength; i > 0; i--) { - bytes32 escrowKey = escrowKeys.at(i - 1); - EscrowKey storage keyInfo = $.escrowKeyToInfo[escrowKey]; - - // First, withdraw any funds that are ready - uint256 withdrawnAmount = _withdraw(auth.buyer, keyInfo.seller, keyInfo.asset); - - // Then, calculate and thaw any remaining balance that isn't already thawing - IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[auth.buyer][keyInfo.seller][keyInfo.asset]; - uint256 availableToThaw = - account.balance > account.thawingAmount ? account.balance - account.thawingAmount : 0; - - uint256 thawedAmount = 0; - if (availableToThaw > 0) { - thawedAmount = _thaw(auth.buyer, keyInfo.seller, keyInfo.asset, availableToThaw); - } - - // Count accounts that had activity - if (withdrawnAmount > 0 || thawedAmount > 0) { - accountsFlushed++; - } - } - - emit FlushAllAuthorized(auth.buyer, auth.nonce, accountsFlushed); + } + + /** + * @notice Get escrow account details for a buyer-seller-asset combination + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @return EscrowAccount struct with balance, thawing amount, and thaw end time + */ + function getAccount(address buyer, address seller, address asset) external view returns (EscrowAccount memory) { + return _getMainStorage().accounts[buyer][seller][asset]; + } + + /** + * @notice Get the balance of an escrow account for a specific buyer-seller-asset combination + * deducting oustanding amounts for the given vouchers + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param voucherIds Unique identifiers of the vouchers + * @param valueAggregates Value aggregates of the vouchers, order must match voucherIds + * @return Balance of the escrow account + */ + function getAccountBalance( + address buyer, + address seller, + address asset, + bytes32[] memory voucherIds, + uint256[] memory valueAggregates + ) external view returns (uint256) { + EscrowAccount memory account = _getMainStorage().accounts[buyer][seller][asset]; + uint256 balance = account.balance - account.thawingAmount; + for (uint256 i = 0; i < voucherIds.length; i++) { + uint256 alreadyCollected = _getMainStorage().voucherCollected[buyer][seller][asset][voucherIds[i]]; + uint256 toCollect = valueAggregates[i] > alreadyCollected ? valueAggregates[i] - alreadyCollected : 0; + if (balance >= toCollect) { + balance -= toCollect; + } else { + balance = 0; + break; + } } - - /** - * @notice Collect a single voucher - * @param voucher The voucher to collect - * @param signature Buyer's signature for the voucher - */ - function collect(Voucher calldata voucher, bytes calldata signature) external nonReentrant { - _collectVoucher(voucher, signature); + return balance; + } + + /** + * @notice Get the amount already collected for a specific voucher + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param voucherId Unique identifier of the voucher + * @return Amount already collected + */ + function getVoucherCollected( + address buyer, + address seller, + address asset, + bytes32 voucherId + ) external view returns (uint256) { + return _getMainStorage().voucherCollected[buyer][seller][asset][voucherId]; + } + + /** + * @notice Calculate the outstanding and collectable amounts for a voucher + * @param voucher The voucher to check + * @return outstanding Total amount still owed on the voucher + * @return collectable Amount that can actually be collected now (considering available balance) + */ + function getOutstandingAndCollectableAmount( + Voucher calldata voucher + ) external view returns (uint256 outstanding, uint256 collectable) { + MainStorage storage $ = _getMainStorage(); + uint256 alreadyCollected = $.voucherCollected[voucher.buyer][voucher.seller][voucher.asset][voucher.id]; + return _getOutstandingAndCollectableAmount(voucher, alreadyCollected); + } + + /** + * @notice Validate a voucher signature + * @param voucher The voucher to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isVoucherSignatureValid(Voucher calldata voucher, bytes calldata signature) external view returns (bool) { + return EscrowSignatureLib.isVoucherSignatureValid(voucher, signature, _domainSeparatorV4()); + } + + /** + * @notice Validate a deposit authorization signature + * @param auth The deposit authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isDepositAuthorizationValid( + DepositAuthorization calldata auth, + bytes calldata signature + ) external view returns (bool) { + return EscrowSignatureLib.isDepositAuthorizationValid(auth, signature, _domainSeparatorV4()); + } + + /** + * @notice Validate a flush authorization signature + * @param auth The flush authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isFlushAuthorizationValid( + FlushAuthorization calldata auth, + bytes calldata signature + ) external view returns (bool) { + return EscrowSignatureLib.isFlushAuthorizationValid(auth, signature, _domainSeparatorV4()); + } + + /** + * @notice Validate a flush all authorization signature + * @param auth The flush all authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isFlushAllAuthorizationValid( + FlushAllAuthorization calldata auth, + bytes calldata signature + ) external view returns (bool) { + return EscrowSignatureLib.isFlushAllAuthorizationValid(auth, signature, _domainSeparatorV4()); + } + + /** + * @notice Validate a deposit authorization nonce + * @param buyer Address of the buyer + * @param nonce The nonce to validate + * @return True if nonce is used + */ + function isDepositAuthorizationNonceUsed(address buyer, bytes32 nonce) external view returns (bool) { + return _getMainStorage().usedDepositNonces[buyer][nonce]; + } + + /** + * @notice Validate a flush authorization nonce + * @param buyer Address of the buyer + * @param nonce The nonce to validate + * @return True if nonce is used + */ + function isFlushAuthorizationNonceUsed(address buyer, bytes32 nonce) external view returns (bool) { + return _getMainStorage().usedFlushNonces[buyer][nonce]; + } + + /** + * @notice Validate a flush all authorization nonce + * @param buyer Address of the buyer + * @param nonce The nonce to validate + * @return True if nonce is used + */ + function isFlushAllAuthorizationNonceUsed(address buyer, bytes32 nonce) external view returns (bool) { + return _getMainStorage().usedFlushAllNonces[buyer][nonce]; + } + + /** + * @notice Get the EIP-712 domain separator + * @return Domain separator hash + */ + function DOMAIN_SEPARATOR() external view returns (bytes32) { + return _domainSeparatorV4(); + } + + /** + * @notice Internal function to collect a voucher + * @param voucher The voucher to collect + * @param signature Buyer's signature for the voucher + */ + function _collectVoucher(Voucher calldata voucher, bytes calldata signature) internal { + // Validate basic voucher parameters + require(voucher.buyer != address(0), InvalidAddress(voucher.buyer)); + require(voucher.asset != address(0), InvalidAsset(voucher.asset)); + require(voucher.escrow == address(this), InvalidEscrow(voucher.escrow, address(this))); + require(voucher.chainId == block.chainid, InvalidChainId(voucher.chainId, block.chainid)); + require(voucher.valueAggregate != 0, InvalidAmount(voucher.valueAggregate)); + require(block.timestamp <= voucher.expiry, VoucherExpired(voucher.id, block.timestamp, voucher.expiry)); + + // Validate signature + require( + EscrowSignatureLib.isVoucherSignatureValid(voucher, signature, _domainSeparatorV4()), + InvalidSignature(voucher.id, voucher.buyer) + ); + + MainStorage storage $ = _getMainStorage(); + + // Get current collected amount and calculate what can be collected + uint256 alreadyCollected = $.voucherCollected[voucher.buyer][voucher.seller][voucher.asset][voucher.id]; + (uint256 outstanding, uint256 collectAmount) = _getOutstandingAndCollectableAmount(voucher, alreadyCollected); + + if (outstanding == 0) { + // Voucher is already fully collected + emit VoucherAlreadyCollected(voucher.id, voucher.buyer, voucher.seller, voucher.asset, alreadyCollected); + return; } - /** - * @notice Collect multiple vouchers in a single transaction - * @param vouchers Array of signed vouchers - */ - function collectMany(SignedVoucher[] calldata vouchers) external nonReentrant { - require(vouchers.length != 0, NoVouchersProvided()); - - for (uint256 i = 0; i < vouchers.length; i++) { - _collectVoucher(vouchers[i].voucher, vouchers[i].signature); - } + if (collectAmount == 0) { + // Voucher has outstanding amount but no balance available + emit VoucherNoCollectableBalance( + voucher.id, + voucher.buyer, + voucher.seller, + voucher.asset, + outstanding, + alreadyCollected + ); + return; } - /** - * @notice Get escrow account details for a buyer-seller-asset combination - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @return EscrowAccount struct with balance, thawing amount, and thaw end time - */ - function getAccount(address buyer, address seller, address asset) external view returns (EscrowAccount memory) { - return _getMainStorage().accounts[buyer][seller][asset]; - } + // Proceed with collection + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[voucher.buyer][voucher.seller][voucher.asset]; - /** - * @notice Get the amount already collected for a specific voucher - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param voucherId Unique identifier of the voucher - * @return Amount already collected - */ - function getVoucherCollected(address buyer, address seller, address asset, bytes32 voucherId) - external - view - returns (uint256) - { - return _getMainStorage().voucherCollected[buyer][seller][asset][voucherId]; - } + // Update state + $.voucherCollected[voucher.buyer][voucher.seller][voucher.asset][voucher.id] = alreadyCollected + collectAmount; - /** - * @notice Calculate the outstanding and collectable amounts for a voucher - * @param voucher The voucher to check - * @return outstanding Total amount still owed on the voucher - * @return collectable Amount that can actually be collected now (considering available balance) - */ - function getOutstandingAndCollectableAmount(Voucher calldata voucher) - external - view - returns (uint256 outstanding, uint256 collectable) - { - MainStorage storage $ = _getMainStorage(); - uint256 alreadyCollected = $.voucherCollected[voucher.buyer][voucher.seller][voucher.asset][voucher.id]; - return _getOutstandingAndCollectableAmount(voucher, alreadyCollected); - } + // Deduct from balance + account.balance -= collectAmount; - /** - * @notice Validate a voucher signature - * @param voucher The voucher to validate - * @param signature The signature to validate - * @return True if signature is valid - */ - function isVoucherSignatureValid(Voucher calldata voucher, bytes calldata signature) external view returns (bool) { - return EscrowSignatureLib.isVoucherSignatureValid(voucher, signature, _domainSeparatorV4()); + // If balance drops below thawing amount, adjust thawing amount + if (account.balance < account.thawingAmount) { + account.thawingAmount = account.balance; } - /** - * @notice Validate a deposit authorization signature - * @param auth The deposit authorization to validate - * @param signature The signature to validate - * @return True if signature is valid - */ - function isDepositAuthorizationValid(DepositAuthorization calldata auth, bytes calldata signature) - external - view - returns (bool) - { - return EscrowSignatureLib.isDepositAuthorizationValid(auth, signature, _domainSeparatorV4()); + // Transfer tokens directly to seller (no protocol fee) + IERC20(voucher.asset).safeTransfer(voucher.seller, collectAmount); + + emit VoucherCollected( + voucher.id, + voucher.buyer, + voucher.seller, + voucher.asset, + collectAmount, + alreadyCollected + collectAmount + ); + + // Clean up if account is empty + if (account.balance == 0 && account.thawingAmount == 0) { + bytes32 key = keccak256(abi.encodePacked(voucher.seller, voucher.asset)); + $.buyerEscrowKeys[voucher.buyer].remove(key); } - - /** - * @notice Validate a flush authorization signature - * @param auth The flush authorization to validate - * @param signature The signature to validate - * @return True if signature is valid - */ - function isFlushAuthorizationValid(FlushAuthorization calldata auth, bytes calldata signature) - external - view - returns (bool) - { - return EscrowSignatureLib.isFlushAuthorizationValid(auth, signature, _domainSeparatorV4()); + } + + /** + * @notice Internal function to handle deposits + * @param buyer Address of the buyer who will own the escrow + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + * @param payer Address paying for the deposit + */ + function _deposit(address buyer, address seller, address asset, uint256 amount, address payer) internal { + require(seller != address(0), InvalidAddress(seller)); + require(asset != address(0), InvalidAsset(asset)); + require(amount != 0, InvalidAmount(amount)); + + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[buyer][seller][asset]; + + // Transfer tokens from payer to this contract + IERC20(asset).safeTransferFrom(payer, address(this), amount); + + // Update account balance + account.balance += amount; + + // Track account in buyerEscrowKeys set + bytes32 key = keccak256(abi.encodePacked(seller, asset)); + if ($.buyerEscrowKeys[buyer].add(key)) { + $.escrowKeyToInfo[key] = EscrowKey(seller, asset); } - /** - * @notice Validate a flush all authorization signature - * @param auth The flush all authorization to validate - * @param signature The signature to validate - * @return True if signature is valid - */ - function isFlushAllAuthorizationValid(FlushAllAuthorization calldata auth, bytes calldata signature) - external - view - returns (bool) - { - return EscrowSignatureLib.isFlushAllAuthorizationValid(auth, signature, _domainSeparatorV4()); + emit Deposited(buyer, seller, asset, amount, account.balance); + } + + /** + * @notice Internal function to initiate or increase thawing + * @dev This function will NOT revert if the requested amount exceeds the available balance. + * Instead, it will cap the thaw amount to the maximum available (balance - already thawing). + * If funds are already thawing, this will ADD to the thawing amount and reset the timer. + * The thaw timer always resets to a full thawing period from the current timestamp, + * regardless of any previous thaw progress. + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to thaw (must be > 0) + * @return thawedAmount The actual amount that was set to thaw (may be less than requested if capped) + */ + function _thaw(address buyer, address seller, address asset, uint256 amount) internal returns (uint256 thawedAmount) { + require(amount > 0, InvalidAmount(amount)); + + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[buyer][seller][asset]; + + // Calculate how much can be thawed + uint256 availableToThaw = account.balance - account.thawingAmount; + if (availableToThaw == 0) { + return 0; // Nothing to thaw } - /** - * @notice Validate a deposit authorization nonce - * @param buyer Address of the buyer - * @param nonce The nonce to validate - * @return True if nonce is used - */ - function isDepositAuthorizationNonceUsed(address buyer, bytes32 nonce) external view returns (bool) { - return _getMainStorage().usedDepositNonces[buyer][nonce]; + // Cap to available amount + thawedAmount = amount > availableToThaw ? availableToThaw : amount; + + // Store previous values for event + uint256 previousThawingAmount = account.thawingAmount; + uint256 previousThawEndTime = account.thawEndTime; + + // Update thawing state + account.thawingAmount = previousThawingAmount + thawedAmount; + account.thawEndTime = uint64(block.timestamp + THAWING_PERIOD); + + emit ThawInitiated( + buyer, + seller, + asset, + account.thawingAmount, + previousThawingAmount, + account.thawEndTime, + previousThawEndTime + ); + } + + /** + * @notice Internal function to withdraw funds that have completed thawing + * @dev This function will NOT revert if there are no funds ready to withdraw. + * It will simply return 0 if: + * - No funds are currently thawing (thawingAmount == 0) + * - The thaw period hasn't completed yet (block.timestamp < thawEndTime) + * The function automatically handles edge cases like collections during thaw period + * by capping the withdrawal to the actual balance if needed. + * If the account becomes empty after withdrawal, it is automatically cleaned up + * and removed from the buyer's escrow keys set. + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @return withdrawnAmount The actual amount withdrawn (0 if nothing was ready) + */ + function _withdraw(address buyer, address seller, address asset) internal returns (uint256 withdrawnAmount) { + MainStorage storage $ = _getMainStorage(); + IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[buyer][seller][asset]; + + // Check if there's anything to withdraw + if (account.thawingAmount == 0 || block.timestamp < account.thawEndTime) { + return 0; // Nothing ready to withdraw } - /** - * @notice Validate a flush authorization nonce - * @param buyer Address of the buyer - * @param nonce The nonce to validate - * @return True if nonce is used - */ - function isFlushAuthorizationNonceUsed(address buyer, bytes32 nonce) external view returns (bool) { - return _getMainStorage().usedFlushNonces[buyer][nonce]; - } + withdrawnAmount = account.thawingAmount; - /** - * @notice Validate a flush all authorization nonce - * @param buyer Address of the buyer - * @param nonce The nonce to validate - * @return True if nonce is used - */ - function isFlushAllAuthorizationNonceUsed(address buyer, bytes32 nonce) external view returns (bool) { - return _getMainStorage().usedFlushAllNonces[buyer][nonce]; + // Ensure balance still covers the thawing amount (in case of collections during thaw) + if (withdrawnAmount > account.balance) { + withdrawnAmount = account.balance; } - /** - * @notice Get the EIP-712 domain separator - * @return Domain separator hash - */ - function DOMAIN_SEPARATOR() external view returns (bytes32) { - return _domainSeparatorV4(); - } + // Update balance and clear thawing state + account.balance -= withdrawnAmount; + account.thawingAmount = 0; + account.thawEndTime = 0; - /** - * @notice Internal function to collect a voucher - * @param voucher The voucher to collect - * @param signature Buyer's signature for the voucher - */ - function _collectVoucher(Voucher calldata voucher, bytes calldata signature) internal { - // Validate basic voucher parameters - require(voucher.buyer != address(0), InvalidAddress(voucher.buyer)); - require(voucher.asset != address(0), InvalidAsset(voucher.asset)); - require(voucher.escrow == address(this), InvalidEscrow(voucher.escrow, address(this))); - require(voucher.chainId == block.chainid, InvalidChainId(voucher.chainId, block.chainid)); - require(voucher.valueAggregate != 0, InvalidAmount(voucher.valueAggregate)); - require(block.timestamp <= voucher.expiry, VoucherExpired(voucher.id, block.timestamp, voucher.expiry)); - - // Validate signature - require( - EscrowSignatureLib.isVoucherSignatureValid(voucher, signature, _domainSeparatorV4()), - InvalidSignature(voucher.id, voucher.buyer) - ); - - MainStorage storage $ = _getMainStorage(); - - // Get current collected amount and calculate what can be collected - uint256 alreadyCollected = $.voucherCollected[voucher.buyer][voucher.seller][voucher.asset][voucher.id]; - (uint256 outstanding, uint256 collectAmount) = _getOutstandingAndCollectableAmount(voucher, alreadyCollected); - - if (outstanding == 0) { - // Voucher is already fully collected - emit VoucherAlreadyCollected(voucher.id, voucher.buyer, voucher.seller, voucher.asset, alreadyCollected); - return; - } - - if (collectAmount == 0) { - // Voucher has outstanding amount but no balance available - emit VoucherNoCollectableBalance( - voucher.id, voucher.buyer, voucher.seller, voucher.asset, outstanding, alreadyCollected - ); - return; - } - - // Proceed with collection - IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[voucher.buyer][voucher.seller][voucher.asset]; - - // Update state - $.voucherCollected[voucher.buyer][voucher.seller][voucher.asset][voucher.id] = alreadyCollected + collectAmount; - - // Deduct from balance - account.balance -= collectAmount; - - // If balance drops below thawing amount, adjust thawing amount - if (account.balance < account.thawingAmount) { - account.thawingAmount = account.balance; - } - - // Transfer tokens directly to seller (no protocol fee) - IERC20(voucher.asset).safeTransfer(voucher.seller, collectAmount); - - emit VoucherCollected( - voucher.id, voucher.buyer, voucher.seller, voucher.asset, collectAmount, alreadyCollected + collectAmount - ); - - // Clean up if account is empty - if (account.balance == 0 && account.thawingAmount == 0) { - bytes32 key = keccak256(abi.encodePacked(voucher.seller, voucher.asset)); - $.buyerEscrowKeys[voucher.buyer].remove(key); - } + // Transfer tokens to buyer + if (withdrawnAmount > 0) { + IERC20(asset).safeTransfer(buyer, withdrawnAmount); + emit Withdrawn(buyer, seller, asset, withdrawnAmount, account.balance); } - /** - * @notice Internal function to handle deposits - * @param buyer Address of the buyer who will own the escrow - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount to deposit - * @param payer Address paying for the deposit - */ - function _deposit(address buyer, address seller, address asset, uint256 amount, address payer) internal { - require(seller != address(0), InvalidAddress(seller)); - require(asset != address(0), InvalidAsset(asset)); - require(amount != 0, InvalidAmount(amount)); - - MainStorage storage $ = _getMainStorage(); - IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[buyer][seller][asset]; - - // Transfer tokens from payer to this contract - IERC20(asset).safeTransferFrom(payer, address(this), amount); - - // Update account balance - account.balance += amount; - - // Track account in buyerEscrowKeys set - bytes32 key = keccak256(abi.encodePacked(seller, asset)); - if ($.buyerEscrowKeys[buyer].add(key)) { - $.escrowKeyToInfo[key] = EscrowKey(seller, asset); - } - - emit Deposited(buyer, seller, asset, amount, account.balance); + // Clean up if account is empty + if (account.balance == 0 && account.thawingAmount == 0) { + bytes32 key = keccak256(abi.encodePacked(seller, asset)); + $.buyerEscrowKeys[buyer].remove(key); } - - /** - * @notice Internal function to initiate or increase thawing - * @dev This function will NOT revert if the requested amount exceeds the available balance. - * Instead, it will cap the thaw amount to the maximum available (balance - already thawing). - * If funds are already thawing, this will ADD to the thawing amount and reset the timer. - * The thaw timer always resets to a full thawing period from the current timestamp, - * regardless of any previous thaw progress. - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount to thaw (must be > 0) - * @return thawedAmount The actual amount that was set to thaw (may be less than requested if capped) - */ - function _thaw(address buyer, address seller, address asset, uint256 amount) - internal - returns (uint256 thawedAmount) - { - require(amount > 0, InvalidAmount(amount)); - - MainStorage storage $ = _getMainStorage(); - IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[buyer][seller][asset]; - - // Calculate how much can be thawed - uint256 availableToThaw = account.balance - account.thawingAmount; - if (availableToThaw == 0) { - return 0; // Nothing to thaw - } - - // Cap to available amount - thawedAmount = amount > availableToThaw ? availableToThaw : amount; - - // Store previous values for event - uint256 previousThawingAmount = account.thawingAmount; - uint256 previousThawEndTime = account.thawEndTime; - - // Update thawing state - account.thawingAmount = previousThawingAmount + thawedAmount; - account.thawEndTime = uint64(block.timestamp + THAWING_PERIOD); - - emit ThawInitiated( - buyer, seller, asset, account.thawingAmount, previousThawingAmount, account.thawEndTime, previousThawEndTime - ); - } - - /** - * @notice Internal function to withdraw funds that have completed thawing - * @dev This function will NOT revert if there are no funds ready to withdraw. - * It will simply return 0 if: - * - No funds are currently thawing (thawingAmount == 0) - * - The thaw period hasn't completed yet (block.timestamp < thawEndTime) - * The function automatically handles edge cases like collections during thaw period - * by capping the withdrawal to the actual balance if needed. - * If the account becomes empty after withdrawal, it is automatically cleaned up - * and removed from the buyer's escrow keys set. - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @return withdrawnAmount The actual amount withdrawn (0 if nothing was ready) - */ - function _withdraw(address buyer, address seller, address asset) internal returns (uint256 withdrawnAmount) { - MainStorage storage $ = _getMainStorage(); - IDeferredPaymentEscrow.EscrowAccount storage account = $.accounts[buyer][seller][asset]; - - // Check if there's anything to withdraw - if (account.thawingAmount == 0 || block.timestamp < account.thawEndTime) { - return 0; // Nothing ready to withdraw - } - - withdrawnAmount = account.thawingAmount; - - // Ensure balance still covers the thawing amount (in case of collections during thaw) - if (withdrawnAmount > account.balance) { - withdrawnAmount = account.balance; - } - - // Update balance and clear thawing state - account.balance -= withdrawnAmount; - account.thawingAmount = 0; - account.thawEndTime = 0; - - // Transfer tokens to buyer - if (withdrawnAmount > 0) { - IERC20(asset).safeTransfer(buyer, withdrawnAmount); - emit Withdrawn(buyer, seller, asset, withdrawnAmount, account.balance); - } - - // Clean up if account is empty - if (account.balance == 0 && account.thawingAmount == 0) { - bytes32 key = keccak256(abi.encodePacked(seller, asset)); - $.buyerEscrowKeys[buyer].remove(key); - } - } - - /** - * @notice Internal function to calculate outstanding and collectable amounts - * @param voucher The voucher to check - * @param alreadyCollected Amount already collected for this voucher - * @return outstanding Total amount still owed on the voucher - * @return collectable Amount that can actually be collected now - */ - function _getOutstandingAndCollectableAmount(Voucher calldata voucher, uint256 alreadyCollected) - internal - view - returns (uint256 outstanding, uint256 collectable) - { - outstanding = 0; - collectable = 0; - - if (voucher.valueAggregate > alreadyCollected) { - outstanding = voucher.valueAggregate - alreadyCollected; - - MainStorage storage $ = _getMainStorage(); - EscrowAccount memory account = $.accounts[voucher.buyer][voucher.seller][voucher.asset]; - - // Full balance is available for collection (thawing doesn't block sellers) - collectable = outstanding > account.balance ? account.balance : outstanding; - } + } + + /** + * @notice Internal function to calculate outstanding and collectable amounts + * @param voucher The voucher to check + * @param alreadyCollected Amount already collected for this voucher + * @return outstanding Total amount still owed on the voucher + * @return collectable Amount that can actually be collected now + */ + function _getOutstandingAndCollectableAmount( + Voucher calldata voucher, + uint256 alreadyCollected + ) internal view returns (uint256 outstanding, uint256 collectable) { + outstanding = 0; + collectable = 0; + + if (voucher.valueAggregate > alreadyCollected) { + outstanding = voucher.valueAggregate - alreadyCollected; + + MainStorage storage $ = _getMainStorage(); + EscrowAccount memory account = $.accounts[voucher.buyer][voucher.seller][voucher.asset]; + + // Full balance is available for collection (thawing doesn't block sellers) + collectable = outstanding > account.balance ? account.balance : outstanding; } + } } diff --git a/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol b/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol index e5c8a1d42a..dc458fa05c 100644 --- a/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol +++ b/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol @@ -7,470 +7,509 @@ pragma solidity ^0.8.4; * @dev Enables micropayments between buyers and sellers using EIP-712 signed vouchers */ interface IDeferredPaymentEscrow { - // ============ ERRORS ============ - - error InvalidAddress(address provided); - error InvalidAmount(uint256 provided); - error InvalidAsset(address provided); - error InvalidThawingPeriod(uint256 provided, uint256 maximum); - error InsufficientBalance(uint256 available, uint256 requested); - error NoThawingInProgress(address buyer, address seller, address asset); - error ThawingPeriodNotCompleted(uint256 currentTime, uint256 thawEndTime); - error InvalidEscrow(address provided, address expected); - error InvalidChainId(uint256 provided, uint256 expected); - error VoucherExpired(bytes32 voucherId, uint256 currentTime, uint256 expiry); - error InvalidSignature(bytes32 voucherId, address buyer); - error NoDepositsProvided(); - error NoVouchersProvided(); - error AuthorizationExpired(uint64 expiry, uint256 currentTime); - error NonceAlreadyUsed(bytes32 nonce); - error InvalidAuthorization(); - - // ============ STRUCTS ============ - - /** - * @notice Represents an escrow account for a specific buyer-seller-asset combination - * @param balance Current deposited balance available for payments - * @param thawingAmount Amount currently in the thawing process - * @param thawEndTime Timestamp when the thawing period completes - */ - struct EscrowAccount { - uint256 balance; - uint256 thawingAmount; - uint64 thawEndTime; - } - - /** - * @notice Represents a payment voucher with all required fields - * @param id Unique identifier for the voucher (unique per buyer-seller pair) - * @param buyer Address of the payment initiator - * @param seller Address of the payment recipient - * @param valueAggregate Total outstanding amount (monotonically increasing) - * @param asset ERC-20 token address - * @param timestamp Last aggregation timestamp - * @param nonce Incremented with each aggregation - * @param escrow Address of this escrow contract - * @param chainId Network chain ID - * @param expiry Expiration timestamp after which voucher cannot be collected - */ - struct Voucher { - bytes32 id; - address buyer; - address seller; - uint256 valueAggregate; - address asset; - uint64 timestamp; - uint256 nonce; - address escrow; - uint256 chainId; - uint64 expiry; - } - - /** - * @notice Input structure for batch deposits - * @param seller Address of the seller to deposit for - * @param amount Amount to deposit - */ - struct DepositInput { - address seller; - uint256 amount; - } - - /** - * @notice Signed voucher (Input structure for batch voucher collections) - * @param voucher The voucher to collect - * @param signature Buyer's signature for the voucher - * @param amount Amount to collect (0 means collect all available) - */ - struct SignedVoucher { - Voucher voucher; - bytes signature; - } - - /** - * @notice Authorization for depositing funds into escrow - * @param buyer Address of the buyer authorizing the deposit - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount to deposit - * @param nonce Random bytes32 for replay protection - * @param expiry Expiration timestamp - */ - struct DepositAuthorization { - address buyer; - address seller; - address asset; - uint256 amount; - bytes32 nonce; - uint64 expiry; - } - - /** - * @notice Authorization for flushing a specific escrow - * @param buyer Address of the buyer authorizing the flush - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param nonce Random bytes32 for replay protection - * @param expiry Expiration timestamp - */ - struct FlushAuthorization { - address buyer; - address seller; - address asset; - bytes32 nonce; - uint64 expiry; - } - - /** - * @notice Authorization for flushing all escrows for a buyer - * @param buyer Address of the buyer authorizing the flush - * @param nonce Random bytes32 for replay protection - * @param expiry Expiration timestamp - */ - struct FlushAllAuthorization { - address buyer; - bytes32 nonce; - uint64 expiry; - } - - // ============ EVENTS ============ - - /** - * @notice Emitted when funds are deposited into an escrow account - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount deposited - * @param newBalance New total balance for the account - */ - event Deposited( - address indexed buyer, address indexed seller, address indexed asset, uint256 amount, uint256 newBalance - ); - - /** - * @notice Emitted when a thawing process is initiated or increased - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param newThawingAmount New total amount being thawed - * @param previousThawingAmount Previous amount that was thawing (0 if new thaw) - * @param newThawEndTime New timestamp when thawing completes - * @param previousThawEndTime Previous thaw end time (0 if new thaw) - */ - event ThawInitiated( - address indexed buyer, - address indexed seller, - address indexed asset, - uint256 newThawingAmount, - uint256 previousThawingAmount, - uint256 newThawEndTime, - uint256 previousThawEndTime - ); - - /** - * @notice Emitted when a thawing process is cancelled - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount that was being thawed - */ - event ThawCancelled(address indexed buyer, address indexed seller, address indexed asset, uint256 amount); - - /** - * @notice Emitted when funds are withdrawn from an escrow account - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount withdrawn - * @param remainingBalance Remaining balance after withdrawal - */ - event Withdrawn( - address indexed buyer, address indexed seller, address indexed asset, uint256 amount, uint256 remainingBalance - ); - - /** - * @notice Emitted when a voucher is collected - * @param voucherId Unique identifier of the voucher - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount collected - * @param totalCollected Total amount collected for this voucher - */ - event VoucherCollected( - bytes32 indexed voucherId, - address indexed buyer, - address indexed seller, - address asset, - uint256 amount, - uint256 totalCollected - ); - - /** - * @notice Emitted when a voucher collection is skipped because it was already fully collected - * @param voucherId Unique identifier of the voucher - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param totalCollected Total amount already collected for this voucher - */ - event VoucherAlreadyCollected( - bytes32 indexed voucherId, address indexed buyer, address indexed seller, address asset, uint256 totalCollected - ); - - /** - * @notice Emitted when a voucher has outstanding amount but no collectable balance - * @param voucherId Unique identifier of the voucher - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param outstanding Amount still owed on the voucher - * @param alreadyCollected Amount already collected for this voucher - */ - event VoucherNoCollectableBalance( - bytes32 indexed voucherId, - address indexed buyer, - address indexed seller, - address asset, - uint256 outstanding, - uint256 alreadyCollected - ); - - /** - * @notice Emitted when a deposit is made using authorization - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount deposited - * @param nonce Nonce used for the authorization - */ - event DepositAuthorized( - address indexed buyer, address indexed seller, address indexed asset, uint256 amount, bytes32 nonce - ); - - /** - * @notice Emitted when a flush is initiated or completed using authorization - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param nonce Nonce used for the authorization - * @param thawing True if thawing was initiated, false if withdrawal completed - */ - event FlushAuthorized( - address indexed buyer, address indexed seller, address indexed asset, bytes32 nonce, bool thawing - ); - - /** - * @notice Emitted when all escrows are flushed using authorization - * @param buyer Address of the buyer - * @param nonce Nonce used for the authorization - * @param accountsFlushed Number of accounts affected - */ - event FlushAllAuthorized(address indexed buyer, bytes32 nonce, uint256 accountsFlushed); - - // ============ DEPOSIT FUNCTIONS ============ - - /** - * @notice Deposit tokens into escrow for a specific seller and asset - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount to deposit - */ - function deposit(address seller, address asset, uint256 amount) external; - - /** - * @notice Deposit tokens into escrow on behalf of a buyer - * @param buyer Address of the buyer who will own the escrow - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount to deposit - */ - function depositTo(address buyer, address seller, address asset, uint256 amount) external; - - /** - * @notice Deposit tokens for multiple sellers with a single asset in a single transaction - * @param asset ERC-20 token address - * @param deposits Array of deposit inputs - */ - function depositMany(address asset, DepositInput[] calldata deposits) external; - - /** - * @notice Deposit tokens using EIP-712 signed authorization - * @param auth The deposit authorization struct - * @param signature Buyer's signature for the authorization - */ - function depositWithAuthorization(DepositAuthorization calldata auth, bytes calldata signature) external; - - // ============ WITHDRAWAL FUNCTIONS ============ - - /** - * @notice Initiate withdrawal process (starts thawing period) - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param amount Amount to withdraw - */ - function thaw(address seller, address asset, uint256 amount) external; - - /** - * @notice Cancel an ongoing thawing process - * @param seller Address of the seller - * @param asset ERC-20 token address - */ - function cancelThaw(address seller, address asset) external; - - /** - * @notice Complete withdrawal after thawing period - * @param seller Address of the seller - * @param asset ERC-20 token address - */ - function withdraw(address seller, address asset) external; - - /** - * @notice Initiate or complete flush using EIP-712 signed authorization - * @param auth The flush authorization struct - * @param signature Buyer's signature for the authorization - */ - function flushWithAuthorization(FlushAuthorization calldata auth, bytes calldata signature) external; - - /** - * @notice Flush all escrows for a buyer using EIP-712 signed authorization - * @param auth The flush all authorization struct - * @param signature Buyer's signature for the authorization - */ - function flushAllWithAuthorization(FlushAllAuthorization calldata auth, bytes calldata signature) external; - - // ============ COLLECTION FUNCTIONS ============ - - /** - * @notice Collect a single voucher (partial or full) - * @param voucher The voucher to collect - * @param signature Buyer's signature for the voucher - */ - function collect(Voucher calldata voucher, bytes calldata signature) external; - - /** - * @notice Collect multiple vouchers in a single transaction - * @param vouchers Array of signed vouchers - */ - function collectMany(SignedVoucher[] calldata vouchers) external; - - // ============ VIEW FUNCTIONS ============ - - /** - * @notice Get escrow account details for a buyer-seller-asset combination - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @return EscrowAccount struct with balance, thawing amount, and thaw end time - */ - function getAccount(address buyer, address seller, address asset) external view returns (EscrowAccount memory); - - /** - * @notice Get the amount already collected for a specific voucher - * @param buyer Address of the buyer - * @param seller Address of the seller - * @param asset ERC-20 token address - * @param voucherId Unique identifier of the voucher - * @return Amount already collected - */ - function getVoucherCollected(address buyer, address seller, address asset, bytes32 voucherId) - external - view - returns (uint256); - - /** - * @notice Calculate the outstanding and collectable amounts for a voucher - * @param voucher The voucher to check - * @return outstanding Total amount still owed on the voucher - * @return collectable Amount that can actually be collected now (considering available balance) - */ - function getOutstandingAndCollectableAmount(Voucher calldata voucher) - external - view - returns (uint256 outstanding, uint256 collectable); - - /** - * @notice Validate a voucher signature - * @param voucher The voucher to validate - * @param signature The signature to validate - * @return True if signature is valid - */ - function isVoucherSignatureValid(Voucher calldata voucher, bytes calldata signature) external view returns (bool); - - /** - * @notice Validate a deposit authorization signature - * @param auth The deposit authorization to validate - * @param signature The signature to validate - * @return True if signature is valid - */ - function isDepositAuthorizationValid(DepositAuthorization calldata auth, bytes calldata signature) - external - view - returns (bool); - - /** - * @notice Validate a flush authorization signature - * @param auth The flush authorization to validate - * @param signature The signature to validate - * @return True if signature is valid - */ - function isFlushAuthorizationValid(FlushAuthorization calldata auth, bytes calldata signature) - external - view - returns (bool); - - /** - * @notice Validate a flush all authorization signature - * @param auth The flush all authorization to validate - * @param signature The signature to validate - * @return True if signature is valid - */ - function isFlushAllAuthorizationValid(FlushAllAuthorization calldata auth, bytes calldata signature) - external - view - returns (bool); - - /** - * @notice Get the current thawing period - * @return Thawing period in seconds - */ - function THAWING_PERIOD() external view returns (uint256); - - /** - * @notice Get the EIP-712 domain separator - * @return Domain separator hash - */ - function DOMAIN_SEPARATOR() external view returns (bytes32); - - // ============ CONSTANTS ============ - - /** - * @notice Maximum allowed thawing period - * @return Maximum thawing period in seconds (30 days) - */ - function MAX_THAWING_PERIOD() external view returns (uint256); - - /** - * @notice EIP-712 type hash for voucher structure - * @return Type hash for voucher - */ - function VOUCHER_TYPEHASH() external view returns (bytes32); - - /** - * @notice EIP-712 type hash for deposit authorization structure - * @return Type hash for deposit authorization - */ - function DEPOSIT_AUTHORIZATION_TYPEHASH() external view returns (bytes32); - - /** - * @notice EIP-712 type hash for flush authorization structure - * @return Type hash for flush authorization - */ - function FLUSH_AUTHORIZATION_TYPEHASH() external view returns (bytes32); - - /** - * @notice EIP-712 type hash for flush all authorization structure - * @return Type hash for flush all authorization - */ - function FLUSH_ALL_AUTHORIZATION_TYPEHASH() external view returns (bytes32); + // ============ ERRORS ============ + + error InvalidAddress(address provided); + error InvalidAmount(uint256 provided); + error InvalidAsset(address provided); + error InvalidThawingPeriod(uint256 provided, uint256 maximum); + error InsufficientBalance(uint256 available, uint256 requested); + error NoThawingInProgress(address buyer, address seller, address asset); + error ThawingPeriodNotCompleted(uint256 currentTime, uint256 thawEndTime); + error InvalidEscrow(address provided, address expected); + error InvalidChainId(uint256 provided, uint256 expected); + error VoucherExpired(bytes32 voucherId, uint256 currentTime, uint256 expiry); + error InvalidSignature(bytes32 voucherId, address buyer); + error NoDepositsProvided(); + error NoVouchersProvided(); + error AuthorizationExpired(uint64 expiry, uint256 currentTime); + error NonceAlreadyUsed(bytes32 nonce); + error InvalidAuthorization(); + + // ============ STRUCTS ============ + + /** + * @notice Represents an escrow account for a specific buyer-seller-asset combination + * @param balance Current deposited balance available for payments + * @param thawingAmount Amount currently in the thawing process + * @param thawEndTime Timestamp when the thawing period completes + */ + struct EscrowAccount { + uint256 balance; + uint256 thawingAmount; + uint64 thawEndTime; + } + + /** + * @notice Represents a payment voucher with all required fields + * @param id Unique identifier for the voucher (unique per buyer-seller pair) + * @param buyer Address of the payment initiator + * @param seller Address of the payment recipient + * @param valueAggregate Total outstanding amount (monotonically increasing) + * @param asset ERC-20 token address + * @param timestamp Last aggregation timestamp + * @param nonce Incremented with each aggregation + * @param escrow Address of this escrow contract + * @param chainId Network chain ID + * @param expiry Expiration timestamp after which voucher cannot be collected + */ + struct Voucher { + bytes32 id; + address buyer; + address seller; + uint256 valueAggregate; + address asset; + uint64 timestamp; + uint256 nonce; + address escrow; + uint256 chainId; + uint64 expiry; + } + + /** + * @notice Input structure for batch deposits + * @param seller Address of the seller to deposit for + * @param amount Amount to deposit + */ + struct DepositInput { + address seller; + uint256 amount; + } + + /** + * @notice Signed voucher (Input structure for batch voucher collections) + * @param voucher The voucher to collect + * @param signature Buyer's signature for the voucher + * @param amount Amount to collect (0 means collect all available) + */ + struct SignedVoucher { + Voucher voucher; + bytes signature; + } + + /** + * @notice Authorization for depositing funds into escrow + * @param buyer Address of the buyer authorizing the deposit + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + * @param nonce Random bytes32 for replay protection + * @param expiry Expiration timestamp + */ + struct DepositAuthorization { + address buyer; + address seller; + address asset; + uint256 amount; + bytes32 nonce; + uint64 expiry; + } + + /** + * @notice Authorization for flushing a specific escrow + * @param buyer Address of the buyer authorizing the flush + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param nonce Random bytes32 for replay protection + * @param expiry Expiration timestamp + */ + struct FlushAuthorization { + address buyer; + address seller; + address asset; + bytes32 nonce; + uint64 expiry; + } + + /** + * @notice Authorization for flushing all escrows for a buyer + * @param buyer Address of the buyer authorizing the flush + * @param nonce Random bytes32 for replay protection + * @param expiry Expiration timestamp + */ + struct FlushAllAuthorization { + address buyer; + bytes32 nonce; + uint64 expiry; + } + + // ============ EVENTS ============ + + /** + * @notice Emitted when funds are deposited into an escrow account + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount deposited + * @param newBalance New total balance for the account + */ + event Deposited( + address indexed buyer, + address indexed seller, + address indexed asset, + uint256 amount, + uint256 newBalance + ); + + /** + * @notice Emitted when a thawing process is initiated or increased + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param newThawingAmount New total amount being thawed + * @param previousThawingAmount Previous amount that was thawing (0 if new thaw) + * @param newThawEndTime New timestamp when thawing completes + * @param previousThawEndTime Previous thaw end time (0 if new thaw) + */ + event ThawInitiated( + address indexed buyer, + address indexed seller, + address indexed asset, + uint256 newThawingAmount, + uint256 previousThawingAmount, + uint256 newThawEndTime, + uint256 previousThawEndTime + ); + + /** + * @notice Emitted when a thawing process is cancelled + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount that was being thawed + */ + event ThawCancelled(address indexed buyer, address indexed seller, address indexed asset, uint256 amount); + + /** + * @notice Emitted when funds are withdrawn from an escrow account + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount withdrawn + * @param remainingBalance Remaining balance after withdrawal + */ + event Withdrawn( + address indexed buyer, + address indexed seller, + address indexed asset, + uint256 amount, + uint256 remainingBalance + ); + + /** + * @notice Emitted when a voucher is collected + * @param voucherId Unique identifier of the voucher + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount collected + * @param totalCollected Total amount collected for this voucher + */ + event VoucherCollected( + bytes32 indexed voucherId, + address indexed buyer, + address indexed seller, + address asset, + uint256 amount, + uint256 totalCollected + ); + + /** + * @notice Emitted when a voucher collection is skipped because it was already fully collected + * @param voucherId Unique identifier of the voucher + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param totalCollected Total amount already collected for this voucher + */ + event VoucherAlreadyCollected( + bytes32 indexed voucherId, + address indexed buyer, + address indexed seller, + address asset, + uint256 totalCollected + ); + + /** + * @notice Emitted when a voucher has outstanding amount but no collectable balance + * @param voucherId Unique identifier of the voucher + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param outstanding Amount still owed on the voucher + * @param alreadyCollected Amount already collected for this voucher + */ + event VoucherNoCollectableBalance( + bytes32 indexed voucherId, + address indexed buyer, + address indexed seller, + address asset, + uint256 outstanding, + uint256 alreadyCollected + ); + + /** + * @notice Emitted when a deposit is made using authorization + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount deposited + * @param nonce Nonce used for the authorization + */ + event DepositAuthorized( + address indexed buyer, + address indexed seller, + address indexed asset, + uint256 amount, + bytes32 nonce + ); + + /** + * @notice Emitted when a flush is initiated or completed using authorization + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param nonce Nonce used for the authorization + * @param thawing True if thawing was initiated, false if withdrawal completed + */ + event FlushAuthorized( + address indexed buyer, + address indexed seller, + address indexed asset, + bytes32 nonce, + bool thawing + ); + + /** + * @notice Emitted when all escrows are flushed using authorization + * @param buyer Address of the buyer + * @param nonce Nonce used for the authorization + * @param accountsFlushed Number of accounts affected + */ + event FlushAllAuthorized(address indexed buyer, bytes32 nonce, uint256 accountsFlushed); + + // ============ DEPOSIT FUNCTIONS ============ + + /** + * @notice Deposit tokens into escrow for a specific seller and asset + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + */ + function deposit(address seller, address asset, uint256 amount) external; + + /** + * @notice Deposit tokens into escrow on behalf of a buyer + * @param buyer Address of the buyer who will own the escrow + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to deposit + */ + function depositTo(address buyer, address seller, address asset, uint256 amount) external; + + /** + * @notice Deposit tokens for multiple sellers with a single asset in a single transaction + * @param asset ERC-20 token address + * @param deposits Array of deposit inputs + */ + function depositMany(address asset, DepositInput[] calldata deposits) external; + + /** + * @notice Deposit tokens using EIP-712 signed authorization + * @param auth The deposit authorization struct + * @param signature Buyer's signature for the authorization + */ + function depositWithAuthorization(DepositAuthorization calldata auth, bytes calldata signature) external; + + // ============ WITHDRAWAL FUNCTIONS ============ + + /** + * @notice Initiate withdrawal process (starts thawing period) + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param amount Amount to withdraw + */ + function thaw(address seller, address asset, uint256 amount) external; + + /** + * @notice Cancel an ongoing thawing process + * @param seller Address of the seller + * @param asset ERC-20 token address + */ + function cancelThaw(address seller, address asset) external; + + /** + * @notice Complete withdrawal after thawing period + * @param seller Address of the seller + * @param asset ERC-20 token address + */ + function withdraw(address seller, address asset) external; + + /** + * @notice Initiate or complete flush using EIP-712 signed authorization + * @param auth The flush authorization struct + * @param signature Buyer's signature for the authorization + */ + function flushWithAuthorization(FlushAuthorization calldata auth, bytes calldata signature) external; + + /** + * @notice Flush all escrows for a buyer using EIP-712 signed authorization + * @param auth The flush all authorization struct + * @param signature Buyer's signature for the authorization + */ + function flushAllWithAuthorization(FlushAllAuthorization calldata auth, bytes calldata signature) external; + + // ============ COLLECTION FUNCTIONS ============ + + /** + * @notice Collect a single voucher (partial or full) + * @param voucher The voucher to collect + * @param signature Buyer's signature for the voucher + */ + function collect(Voucher calldata voucher, bytes calldata signature) external; + + /** + * @notice Collect multiple vouchers in a single transaction + * @param vouchers Array of signed vouchers + */ + function collectMany(SignedVoucher[] calldata vouchers) external; + + // ============ VIEW FUNCTIONS ============ + + /** + * @notice Get escrow account details for a buyer-seller-asset combination + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @return EscrowAccount struct with balance, thawing amount, and thaw end time + */ + function getAccount(address buyer, address seller, address asset) external view returns (EscrowAccount memory); + + /** + * @notice Get the balance of an escrow account for a specific buyer-seller-asset combination + * deducting oustanding amounts for the given vouchers + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param voucherIds Unique identifiers of the vouchers + * @param valueAggregates Value aggregates of the vouchers, order must match voucherIds + * @return Balance of the escrow account + */ + function getAccountBalance( + address buyer, + address seller, + address asset, + bytes32[] memory voucherIds, + uint256[] memory valueAggregates + ) external view returns (uint256); + + /** + * @notice Get the amount already collected for a specific voucher + * @param buyer Address of the buyer + * @param seller Address of the seller + * @param asset ERC-20 token address + * @param voucherId Unique identifier of the voucher + * @return Amount already collected + */ + function getVoucherCollected( + address buyer, + address seller, + address asset, + bytes32 voucherId + ) external view returns (uint256); + + /** + * @notice Calculate the outstanding and collectable amounts for a voucher + * @param voucher The voucher to check + * @return outstanding Total amount still owed on the voucher + * @return collectable Amount that can actually be collected now (considering available balance) + */ + function getOutstandingAndCollectableAmount( + Voucher calldata voucher + ) external view returns (uint256 outstanding, uint256 collectable); + + /** + * @notice Validate a voucher signature + * @param voucher The voucher to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isVoucherSignatureValid(Voucher calldata voucher, bytes calldata signature) external view returns (bool); + + /** + * @notice Validate a deposit authorization signature + * @param auth The deposit authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isDepositAuthorizationValid( + DepositAuthorization calldata auth, + bytes calldata signature + ) external view returns (bool); + + /** + * @notice Validate a flush authorization signature + * @param auth The flush authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isFlushAuthorizationValid( + FlushAuthorization calldata auth, + bytes calldata signature + ) external view returns (bool); + + /** + * @notice Validate a flush all authorization signature + * @param auth The flush all authorization to validate + * @param signature The signature to validate + * @return True if signature is valid + */ + function isFlushAllAuthorizationValid( + FlushAllAuthorization calldata auth, + bytes calldata signature + ) external view returns (bool); + + /** + * @notice Get the current thawing period + * @return Thawing period in seconds + */ + function THAWING_PERIOD() external view returns (uint256); + + /** + * @notice Get the EIP-712 domain separator + * @return Domain separator hash + */ + function DOMAIN_SEPARATOR() external view returns (bytes32); + + // ============ CONSTANTS ============ + + /** + * @notice Maximum allowed thawing period + * @return Maximum thawing period in seconds (30 days) + */ + function MAX_THAWING_PERIOD() external view returns (uint256); + + /** + * @notice EIP-712 type hash for voucher structure + * @return Type hash for voucher + */ + function VOUCHER_TYPEHASH() external view returns (bytes32); + + /** + * @notice EIP-712 type hash for deposit authorization structure + * @return Type hash for deposit authorization + */ + function DEPOSIT_AUTHORIZATION_TYPEHASH() external view returns (bytes32); + + /** + * @notice EIP-712 type hash for flush authorization structure + * @return Type hash for flush authorization + */ + function FLUSH_AUTHORIZATION_TYPEHASH() external view returns (bytes32); + + /** + * @notice EIP-712 type hash for flush all authorization structure + * @return Type hash for flush all authorization + */ + function FLUSH_ALL_AUTHORIZATION_TYPEHASH() external view returns (bytes32); } diff --git a/typescript/packages/x402-axios/src/index.ts b/typescript/packages/x402-axios/src/index.ts index 3520d86b16..d3cf8cca48 100644 --- a/typescript/packages/x402-axios/src/index.ts +++ b/typescript/packages/x402-axios/src/index.ts @@ -185,6 +185,7 @@ export function withDeferredPaymentInterceptor( network, DEFERRRED_SCHEME, ); + console.log(selectedPaymentRequirements); const selectedDeferredPaymentRequirements = DeferredPaymentRequirementsSchema.parse( selectedPaymentRequirements, ); diff --git a/typescript/packages/x402-express/src/index.ts b/typescript/packages/x402-express/src/index.ts index 7cfd35a42d..ea1c1583fd 100644 --- a/typescript/packages/x402-express/src/index.ts +++ b/typescript/packages/x402-express/src/index.ts @@ -6,6 +6,7 @@ import { computeRoutePatterns, findMatchingPaymentRequirements, findMatchingRoute, + getNetworkId, getPaywallHtml, processPriceToAtomicAmount, toJsonSafe, @@ -427,7 +428,7 @@ export function deferredPaymentMiddleware( payTo: Address, routes: RoutesConfig, escrow: Address, - facilitator?: FacilitatorConfig, + facilitator: FacilitatorConfig, voucherStore?: Pick< InstanceType, "getAvailableVoucher" | "storeVoucher" @@ -497,6 +498,9 @@ export function deferredPaymentMiddleware( paymentBuyer as `0x${string}` | undefined, payTo, escrow, + getAddress(asset.address), + getNetworkId(network), + facilitator, voucherStore ? voucherStore.getAvailableVoucher : facilitatorVoucherStore.getAvailableVoucher, diff --git a/typescript/packages/x402/src/client/createPaymentHeader.ts b/typescript/packages/x402/src/client/createPaymentHeader.ts index db4f056fac..6ded41f604 100644 --- a/typescript/packages/x402/src/client/createPaymentHeader.ts +++ b/typescript/packages/x402/src/client/createPaymentHeader.ts @@ -12,12 +12,14 @@ import { EXACT_SCHEME } from "../types/verify/schemes/exact"; * @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 + * @param extraPayload - Extra payload to be included in the payment header creation, scheme dependent interpretation * @returns A promise that resolves to the created payment header string */ export async function createPaymentHeader( client: Signer | MultiNetworkSigner, x402Version: number, paymentRequirements: PaymentRequirements, + extraPayload?: Record, ): Promise { // exact scheme if (paymentRequirements.scheme === EXACT_SCHEME) { @@ -62,7 +64,7 @@ export async function createPaymentHeader( throw new Error("Invalid evm wallet client provided"); } - return await createPaymentHeaderDeferredEVM(evmClient, x402Version, paymentRequirements); + return await createPaymentHeaderDeferredEVM(evmClient, x402Version, paymentRequirements, extraPayload); } throw new Error("Unsupported scheme"); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts index 6cb8930c05..a32f156474 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -112,6 +112,91 @@ describe("preparePaymentHeader: new voucher", () => { const result = await preparePaymentHeader(buyerAddress, 2, mockPaymentRequirements); expect(result.x402Version).toBe(2); }); + + it("should include depositAuthorization in payload when provided in extraPayload", async () => { + const mockDepositAuthorization = { + permit: { + owner: buyerAddress, + spender: escrowAddress, + value: "1000000", + nonce: 0, + deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, + domain: { + name: "USD Coin", + version: "2", + }, + signature: + "0x1ed1158f8c70dc6393f8c9a379bf4569eb13a0ae6f060465418cbb9acbf5fb536eda5bdb7a6a28317329df0b9aec501fdf15f02f04b60ac536b90da3ce6f3efb1c", + }, + depositAuthorization: { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "1000000", + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b", + }, + }; + + const paymentHeader = await preparePaymentHeader( + buyerAddress, + 1, + mockPaymentRequirements, + mockDepositAuthorization, + ); + + expect(paymentHeader.payload.depositAuthorization).toEqual(mockDepositAuthorization); + expect(paymentHeader.payload.depositAuthorization?.permit).toBeDefined(); + }); + + it("should include depositAuthorization without permit when permit is not provided", async () => { + const mockDepositAuthorizationNoPermit = { + depositAuthorization: { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "1000000", + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b", + }, + }; + + const paymentHeader = await preparePaymentHeader( + buyerAddress, + 1, + mockPaymentRequirements, + mockDepositAuthorizationNoPermit, + ); + + expect(paymentHeader.payload.depositAuthorization).toEqual(mockDepositAuthorizationNoPermit); + expect(paymentHeader.payload.depositAuthorization?.permit).toBeUndefined(); + }); + + it("should not include depositAuthorization when extraPayload is not provided", async () => { + const paymentHeader = await preparePaymentHeader(buyerAddress, 1, mockPaymentRequirements); + + expect(paymentHeader.payload.depositAuthorization).toBeUndefined(); + }); + + it("should throw error when depositAuthorization in extraPayload is invalid", async () => { + const invalidDepositAuthorization = { + permit: { + owner: "invalid-address", // Invalid address format + spender: escrowAddress, + }, + depositAuthorization: { + buyer: buyerAddress, + }, + }; + + await expect( + preparePaymentHeader(buyerAddress, 1, mockPaymentRequirements, invalidDepositAuthorization), + ).rejects.toThrow(); + }); }); describe("createNewVoucher", () => { diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index 3cfda51065..3a05c1b077 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -3,6 +3,7 @@ import { getNetworkId } from "../../../shared/network"; import { isSignerWallet, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, PaymentRequirements, UnsignedPaymentPayload } from "../../../types/verify"; import { + DeferredEscrowDepositAuthorizationSchema, DeferredEvmPayloadVoucher, DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, DeferredEvmPaymentRequirementsExtraNewVoucherSchema, @@ -22,12 +23,14 @@ const EXPIRY_TIME = 60 * 60 * 24 * 30; // 30 days * @param buyer - 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 + * @param extraPayload - Extra payload to be included in the payment header creation * @returns An unsigned payment payload containing authorization details */ export async function preparePaymentHeader( buyer: Address, x402Version: number, paymentRequirements: PaymentRequirements, + extraPayload?: Record, ): Promise { const deferredPaymentRequirements = DeferredPaymentRequirementsSchema.parse(paymentRequirements); @@ -36,6 +39,10 @@ export async function preparePaymentHeader( ? createNewVoucher(buyer, deferredPaymentRequirements) : await aggregateVoucher(buyer, deferredPaymentRequirements); + const depositAuthorization = extraPayload + ? DeferredEscrowDepositAuthorizationSchema.parse(extraPayload) + : undefined; + return { x402Version, scheme: DEFERRRED_SCHEME, @@ -43,6 +50,7 @@ export async function preparePaymentHeader( payload: { signature: undefined, voucher: voucher, + ...(depositAuthorization && { depositAuthorization }), }, } as const satisfies UnsignedDeferredPaymentPayload; } @@ -163,15 +171,22 @@ export async function signPaymentHeader( client: SignerWallet | LocalAccount, x402Version: number, paymentRequirements: PaymentRequirements, + extraPayload?: Record, ): Promise { const from = isSignerWallet(client) ? client.account!.address : client.address; - const unsignedPaymentHeader = await preparePaymentHeader(from, x402Version, paymentRequirements); + const unsignedPaymentHeader = await preparePaymentHeader( + from, + x402Version, + paymentRequirements, + extraPayload, + ); return signPaymentHeader(client, unsignedPaymentHeader); } @@ -181,13 +196,15 @@ export async function createPayment, ): Promise { - const payment = await createPayment(client, x402Version, paymentRequirements); + const payment = await createPayment(client, x402Version, paymentRequirements, extraPayload); return encodePayment(payment); } diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 1b605d8871..7c32793492 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -441,3 +441,67 @@ export async function depositWithAuthorization( + client: ConnectedClient, + buyer: Address, + seller: Address, + asset: Address, + escrow: Address, + chainId: number, + voucherStore: VoucherStore, +): Promise { + const outstandingVouchers = await voucherStore.getVouchers( + { + buyer, + seller, + asset, + escrow, + chainId, + latest: true, + }, + { + limit: 1_000, // TODO: pagination? + }, + ); + + let buyerAccountBalance: bigint; + try { + buyerAccountBalance = await client.readContract({ + address: escrow as Address, + abi: deferredEscrowABI, + functionName: "getAccountBalance", + args: [ + buyer as Address, + seller as Address, + asset as Address, + outstandingVouchers.map(voucher => voucher.id as `0x${string}`), + outstandingVouchers.map(voucher => BigInt(voucher.valueAggregate)), + ], + }); + } catch (error) { + console.log(error); + return { + error: "invalid_deferred_evm_contract_call_failed_account", + }; + } + + return buyerAccountBalance; +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/server.ts b/typescript/packages/x402/src/schemes/deferred/evm/server.ts index 842aa96ea3..aed4090b8d 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/server.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/server.ts @@ -2,10 +2,12 @@ import { Address, getAddress } from "viem"; import { DeferredEvmPayloadSchema, DeferredEvmPayloadSignedVoucher, + FacilitatorConfig, PaymentRequirementsExtra, } from "../../../types"; import { generateVoucherId } from "./id"; import { decodePayment } from "./utils/paymentUtils"; +import { useDeferredFacilitator } from "../../../verify/useDeferred"; /** * Compute the extra data for the payment requirements @@ -14,6 +16,9 @@ import { decodePayment } from "./utils/paymentUtils"; * @param xBuyerHeader - The x-buyer header * @param seller - The seller address * @param escrow - The escrow address + * @param asset - The asset address + * @param chainId - The chain ID + * @param facilitator - The facilitator URL to get escrow balance from * @param getAvailableVoucher - A function to get the latest voucher for a given buyer and seller. * @returns The extra data for the payment requirements */ @@ -22,11 +27,16 @@ export async function getPaymentRequirementsExtra( xBuyerHeader: Address | undefined, seller: Address, escrow: Address, + asset: Address, + chainId: number, + facilitator: FacilitatorConfig, getAvailableVoucher: ( buyer: string, seller: string, ) => Promise, ): Promise { + const { getEscrowAccountBalance } = useDeferredFacilitator(facilitator); + let buyer: Address; const newVoucherExtra = { type: "new" as const, @@ -53,10 +63,22 @@ export async function getPaymentRequirementsExtra( buyer = xBuyerHeader!; // This is safe due to the previous early return } + // Retrieve balance from facilitator -- if it fails return 0n which means the depositWithAuth flow will not be triggered + let balance = 0n; + try { + balance = await getEscrowAccountBalance(buyer, seller, asset, escrow, chainId); + } catch (error) { + console.error(error); + } + const previousVoucher = await getAvailableVoucher(buyer, seller); if (previousVoucher) { return { type: "aggregation" as const, + balance: { + balance: balance.toString(), + facilitator: facilitator.url, + }, signature: previousVoucher.signature, voucher: { ...previousVoucher, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts b/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts index 033d6e2dd2..7f41bb0733 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/store.mock.ts @@ -69,6 +69,9 @@ export class InMemoryVoucherStore extends VoucherStore { * @param query - The query options * @param query.buyer - The buyer's address * @param query.seller - The seller's address + * @param query.asset - The asset's address + * @param query.escrow - The escrow's address + * @param query.chainId - The chain ID * @param query.latest - Whether to return only the latest voucher per series * @param pagination - The pagination options * @param pagination.limit - The maximum number of vouchers to return @@ -79,6 +82,9 @@ export class InMemoryVoucherStore extends VoucherStore { query: { buyer?: string | undefined; seller?: string | undefined; + asset?: string | undefined; + escrow?: string | undefined; + chainId?: number | undefined; latest?: boolean | undefined; }, pagination: { @@ -87,12 +93,15 @@ export class InMemoryVoucherStore extends VoucherStore { }, ): Promise> { const { limit = 100, offset = 0 } = pagination; - const { buyer, latest, seller } = query; + const { buyer, latest, seller, asset, escrow, chainId } = query; // Filter vouchers by buyer and/or seller let filteredVouchers = this.vouchers.filter(voucher => { if (buyer && voucher.buyer !== buyer) return false; if (seller && voucher.seller !== seller) return false; + if (asset && voucher.asset !== asset) return false; + if (escrow && voucher.escrow !== escrow) return false; + if (chainId && voucher.chainId !== chainId) return false; return true; }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/store.ts b/typescript/packages/x402/src/schemes/deferred/evm/store.ts index a1076901b2..295146cda8 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/store.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/store.ts @@ -79,6 +79,9 @@ export abstract class VoucherStore { * Query Options: * - buyer: Filter by buyer's address * - seller: Filter by seller's address + * - asset: Filter by asset's address + * - escrow: Filter by escrow's address + * - chainId: Filter by chain ID * - latest: If true, return only the highest nonce voucher per series * * Behavior: @@ -105,6 +108,9 @@ export abstract class VoucherStore { query: { buyer?: string; seller?: string; + asset?: string; + escrow?: string; + chainId?: number; latest?: boolean; }, pagination: { diff --git a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts index dc4980ba7a..08ff41082b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts @@ -247,4 +247,110 @@ describe("paymentUtils", () => { expect(decoded).toEqual(mixedCasePayload); }); }); + + describe("depositAuthorization handling", () => { + const mockPaymentWithDepositAuth: DeferredPaymentPayload = { + ...mockPaymentPayload, + payload: { + ...mockPaymentPayload.payload, + depositAuthorization: { + permit: { + owner: buyerAddress, + spender: escrowAddress, + value: "1000000", + nonce: 0, + deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, + domain: { + name: "USD Coin", + version: "2", + }, + signature: + "0x1ed1158f8c70dc6393f8c9a379bf4569eb13a0ae6f060465418cbb9acbf5fb536eda5bdb7a6a28317329df0b9aec501fdf15f02f04b60ac536b90da3ce6f3efb1c", + }, + depositAuthorization: { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "1000000", + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b", + }, + }, + }, + }; + + const mockPaymentWithDepositAuthNoPermit: DeferredPaymentPayload = { + ...mockPaymentPayload, + payload: { + ...mockPaymentPayload.payload, + depositAuthorization: { + depositAuthorization: { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "1000000", + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b", + }, + }, + }, + }; + + it("should encode payment with depositAuthorization (with permit)", () => { + const encoded = encodePayment(mockPaymentWithDepositAuth); + + expect(typeof encoded).toBe("string"); + expect(encoded.length).toBeGreaterThan(0); + }); + + it("should decode payment with depositAuthorization (with permit)", () => { + const encoded = encodePayment(mockPaymentWithDepositAuth); + const decoded = decodePayment(encoded) as DeferredPaymentPayload; + + expect(decoded).toEqual(mockPaymentWithDepositAuth); + expect(decoded.payload.depositAuthorization).toBeDefined(); + expect(decoded.payload.depositAuthorization?.permit).toBeDefined(); + expect(decoded.payload.depositAuthorization?.depositAuthorization).toBeDefined(); + }); + + it("should encode payment with depositAuthorization (without permit)", () => { + const encoded = encodePayment(mockPaymentWithDepositAuthNoPermit); + + expect(typeof encoded).toBe("string"); + expect(encoded.length).toBeGreaterThan(0); + }); + + it("should decode payment with depositAuthorization (without permit)", () => { + const encoded = encodePayment(mockPaymentWithDepositAuthNoPermit); + const decoded = decodePayment(encoded) as DeferredPaymentPayload; + + expect(decoded).toEqual(mockPaymentWithDepositAuthNoPermit); + expect(decoded.payload.depositAuthorization).toBeDefined(); + expect(decoded.payload.depositAuthorization?.permit).toBeUndefined(); + expect(decoded.payload.depositAuthorization?.depositAuthorization).toBeDefined(); + }); + + it("should round-trip payment with depositAuthorization", () => { + let current = mockPaymentWithDepositAuth; + + for (let i = 0; i < 3; i++) { + const encoded = encodePayment(current); + current = decodePayment(encoded) as DeferredPaymentPayload; + } + + expect(current).toEqual(mockPaymentWithDepositAuth); + }); + + it("should handle payment without depositAuthorization", () => { + const encoded = encodePayment(mockPaymentPayload); + const decoded = decodePayment(encoded) as DeferredPaymentPayload; + + expect(decoded.payload.depositAuthorization).toBeUndefined(); + expect(decoded).toEqual(mockPaymentPayload); + }); + }); }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts index 163bace907..d154e19fe3 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.ts @@ -13,13 +13,16 @@ export function encodePayment(payment: PaymentPayload): string { const safe = { ...deferredPayment, payload: { - ...payment.payload, + signature: deferredPayment.payload.signature, voucher: Object.fromEntries( Object.entries(deferredPayment.payload.voucher).map(([key, value]) => [ key, typeof value === "bigint" ? (value as bigint).toString() : value, ]), ), + ...(deferredPayment.payload.depositAuthorization && { + depositAuthorization: deferredPayment.payload.depositAuthorization, + }), }, }; return safeBase64Encode(JSON.stringify(safe)); @@ -42,6 +45,9 @@ export function decodePayment(payment: string): PaymentPayload { voucher: { ...parsed.payload.voucher, }, + ...(parsed.payload.depositAuthorization && { + depositAuthorization: parsed.payload.depositAuthorization, + }), }, }; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index 86d89973d5..1e2c5e02bd 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -71,7 +71,7 @@ export function verifyPaymentRequirements( paymentRequirements.extra.type === "new" ? BigInt(paymentRequirements.maxAmountRequired) : BigInt(paymentRequirements.maxAmountRequired) + - BigInt(paymentRequirements.extra.voucher.valueAggregate); + BigInt(paymentRequirements.extra.voucher.valueAggregate); if (BigInt(paymentPayload.payload.voucher.valueAggregate) < requiredVoucherValueAggregate) { return { isValid: false, @@ -455,7 +455,10 @@ export async function verifyOnchainState< }; } - if (buyerAccount.balance + authorizationBalance < voucherOutstandingAmount) { + if ( + buyerAccount.balance - buyerAccount.thawingAmount + authorizationBalance < + voucherOutstandingAmount + ) { return { isValid: false, invalidReason: "insufficient_funds", diff --git a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts index 82223b9aca..c96bffaaa0 100644 --- a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts +++ b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts @@ -262,6 +262,19 @@ export const deferredEscrowABI = [ ], stateMutability: "view", }, + { + type: "function", + name: "getAccountBalance", + inputs: [ + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "voucherIds", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "valueAggregates", type: "uint256[]", internalType: "uint256[]" }, + ], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, { type: "function", name: "getOutstandingAndCollectableAmount", diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 5ce455e71a..8705acf9ec 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -170,9 +170,19 @@ export const UnsignedDeferredPaymentPayloadSchema = BasePaymentPayloadSchema.ext }); export type UnsignedDeferredPaymentPayload = z.infer; +// x402DeferredEvmPaymentRequirementsExtraAccountBalance +export const DeferredEvmPaymentRequirementsExtraAccountBalanceSchema = z.object({ + balance: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + facilitator: z.string(), +}); +export type DeferredEvmPaymentRequirementsExtraAccountBalance = z.infer< + typeof DeferredEvmPaymentRequirementsExtraAccountBalanceSchema +>; + // x402DeferredEvmPaymentRequirementsExtraNewVoucher export const DeferredEvmPaymentRequirementsExtraNewVoucherSchema = z.object({ type: z.literal("new"), + balance: DeferredEvmPaymentRequirementsExtraAccountBalanceSchema.optional(), voucher: DeferredEvmPayloadVoucherSchema.pick({ id: true, escrow: true }), }); export type DeferredEvmPaymentRequirementsExtraNewVoucher = z.infer< @@ -182,6 +192,7 @@ export type DeferredEvmPaymentRequirementsExtraNewVoucher = z.infer< // x402DeferredEvmPaymentRequirementsExtraAggregationVoucher export const DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema = z.object({ type: z.literal("aggregation"), + balance: DeferredEvmPaymentRequirementsExtraAccountBalanceSchema.optional(), signature: z.string().regex(EvmSignatureRegex), voucher: DeferredEvmPayloadVoucherSchema, }); diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index 503f1de005..65d28cff77 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -280,6 +280,33 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { return responseJson; } + /** + * Fetches the balance of an escrow account + * + * @param buyer - The buyer address + * @param seller - The seller address + * @param asset - The asset address + * @param escrow - The escrow address + * @param chainId - The chain ID + * @returns The balance of the escrow account + */ + async function getEscrowAccountBalance( + buyer: string, + seller: string, + asset: string, + escrow: string, + chainId: number, + ): Promise { + const response = await fetch( + `${facilitator.url}/deferred/accounts?buyer=${buyer}&seller=${seller}&asset=${asset}&escrow=${escrow}&chainId=${chainId}`, + ); + const responseJson = (await response.json()) as { balance: string } | { error: string }; + if ("error" in responseJson) { + throw new Error(responseJson.error); + } + return BigInt(responseJson.balance); + } + return { getVoucher, getVouchers, @@ -289,5 +316,6 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { verifyVoucher, settleVoucher, getVoucherCollections, + getEscrowAccountBalance, }; } From 776115723d0aa2a82376b2647ba061a5a32a3729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 13 Oct 2025 16:38:15 -0300 Subject: [PATCH 092/116] feat(deferred): wire client libs to support deposit with auth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- examples/typescript/clients/axios/deferred.ts | 22 +++- .../typescript/servers/express/.env-local | 2 +- solidity/deferred-escrow/addresses.json | 2 +- .../src/DeferredPaymentEscrow.sol | 19 ++- .../src/IDeferredPaymentEscrow.sol | 13 +- typescript/packages/x402-axios/src/index.ts | 16 ++- .../x402/src/schemes/deferred/evm/client.ts | 119 +++++++++++++++++- .../src/schemes/deferred/evm/facilitator.ts | 27 ++-- .../x402/src/schemes/deferred/evm/server.ts | 31 +++-- .../src/types/shared/evm/deferredEscrowABI.ts | 8 +- .../x402/src/types/verify/refiners.ts | 1 + .../x402/src/types/verify/schemes/deferred.ts | 52 ++++++-- .../packages/x402/src/verify/useDeferred.ts | 15 ++- 13 files changed, 274 insertions(+), 53 deletions(-) diff --git a/examples/typescript/clients/axios/deferred.ts b/examples/typescript/clients/axios/deferred.ts index 8174a6284b..fa0d9bae71 100644 --- a/examples/typescript/clients/axios/deferred.ts +++ b/examples/typescript/clients/axios/deferred.ts @@ -35,21 +35,33 @@ async function main(): Promise { baseURL, }), signer, + // [ + // { + // asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + // assetDomain: { + // name: "USDC", + // version: "2", + // }, + // threshold: "996000", + // amount: "100", + // }, + // ], ); - const response = await api.get(endpointPath); - console.log(response.data); - try { + const response = await api.get(endpointPath); + console.log(response.data); + const xPaymentHeader = response.config.headers["X-PAYMENT"]; const paymentPayload = JSON.parse(Buffer.from(xPaymentHeader, "base64").toString("utf-8")); console.log("Deferred voucher details:"); console.log(paymentPayload.payload.voucher); + + const paymentResponse = decodeXPaymentResponse(response.headers["x-payment-response"]); + console.log(paymentResponse); } catch (error) { console.error(error); } - const paymentResponse = decodeXPaymentResponse(response.headers["x-payment-response"]); - console.log(paymentResponse); } main(); diff --git a/examples/typescript/servers/express/.env-local b/examples/typescript/servers/express/.env-local index cc6ef43155..f216d4d803 100644 --- a/examples/typescript/servers/express/.env-local +++ b/examples/typescript/servers/express/.env-local @@ -1,7 +1,7 @@ FACILITATOR_URL=https://x402.org/facilitator NETWORK=base-sepolia ADDRESS= -DEFERRED_ESCROW=0xF1308b39EdB10E5163581C1f8D0Bf8E26404A11f +DEFERRED_ESCROW=0xfda9048c2e6ba55874003a9595c7f90c2d6af1e6 # required if using the Base mainnet facilitator CDP_API_KEY_ID="Coinbase Developer Platform Key" diff --git a/solidity/deferred-escrow/addresses.json b/solidity/deferred-escrow/addresses.json index 5a8cfcb425..75778a8d15 100644 --- a/solidity/deferred-escrow/addresses.json +++ b/solidity/deferred-escrow/addresses.json @@ -1,5 +1,5 @@ { "84532": { - "deferredPaymentEscrow": "0x32f493421eb3e296a2c66505a6ebd1540943a2ac" + "deferredPaymentEscrow": "0xfda9048c2e6ba55874003a9595c7f90c2d6af1e6" } } \ No newline at end of file diff --git a/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol b/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol index 97c1ed9411..f77da3a860 100644 --- a/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol +++ b/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.30; import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import { IDeferredPaymentEscrow } from "./IDeferredPaymentEscrow.sol"; @@ -368,22 +369,27 @@ contract DeferredPaymentEscrow is ReentrancyGuard, EIP712, IDeferredPaymentEscro } /** - * @notice Get the balance of an escrow account for a specific buyer-seller-asset combination - * deducting oustanding amounts for the given vouchers + * @notice Gets buyer account details for a specific buyer-seller-asset combination. + * This returns escrow account balance, ERC20 allowance and permit nonce for the given asset. + * + * It deducts outstanding amounts for the given vouchers from the escrow account balance. + * * @param buyer Address of the buyer * @param seller Address of the seller * @param asset ERC-20 token address * @param voucherIds Unique identifiers of the vouchers * @param valueAggregates Value aggregates of the vouchers, order must match voucherIds * @return Balance of the escrow account + * @return Allowance of the escrow account for the given asset + * @return Permit nonce of the escrow account for the given asset */ - function getAccountBalance( + function getAccountDetails( address buyer, address seller, address asset, bytes32[] memory voucherIds, uint256[] memory valueAggregates - ) external view returns (uint256) { + ) external view returns (uint256, uint256, uint256) { EscrowAccount memory account = _getMainStorage().accounts[buyer][seller][asset]; uint256 balance = account.balance - account.thawingAmount; for (uint256 i = 0; i < voucherIds.length; i++) { @@ -396,7 +402,10 @@ contract DeferredPaymentEscrow is ReentrancyGuard, EIP712, IDeferredPaymentEscro break; } } - return balance; + uint256 allowance = IERC20(asset).allowance(buyer, address(this)); + uint256 nonce = IERC20Permit(asset).nonces(buyer); + + return (balance, allowance, nonce); } /** diff --git a/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol b/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol index dc458fa05c..c29de638d6 100644 --- a/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol +++ b/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol @@ -386,22 +386,27 @@ interface IDeferredPaymentEscrow { function getAccount(address buyer, address seller, address asset) external view returns (EscrowAccount memory); /** - * @notice Get the balance of an escrow account for a specific buyer-seller-asset combination - * deducting oustanding amounts for the given vouchers + * @notice Gets buyer account details for a specific buyer-seller-asset combination. + * This returns escrow account balance, ERC20 allowance and permit nonce for the given asset. + * + * It deducts outstanding amounts for the given vouchers from the escrow account balance. + * * @param buyer Address of the buyer * @param seller Address of the seller * @param asset ERC-20 token address * @param voucherIds Unique identifiers of the vouchers * @param valueAggregates Value aggregates of the vouchers, order must match voucherIds * @return Balance of the escrow account + * @return Allowance of the escrow account for the given asset + * @return Permit nonce of the escrow account for the given asset */ - function getAccountBalance( + function getAccountDetails( address buyer, address seller, address asset, bytes32[] memory voucherIds, uint256[] memory valueAggregates - ) external view returns (uint256); + ) external view returns (uint256, uint256, uint256); /** * @notice Get the amount already collected for a specific voucher diff --git a/typescript/packages/x402-axios/src/index.ts b/typescript/packages/x402-axios/src/index.ts index d3cf8cca48..67e501e96a 100644 --- a/typescript/packages/x402-axios/src/index.ts +++ b/typescript/packages/x402-axios/src/index.ts @@ -5,6 +5,7 @@ import { PaymentRequirementsSelector, selectPaymentRequirements, } from "x402/client"; +import { deferred } from "x402/schemes"; import { Signer, MultiNetworkSigner, @@ -18,6 +19,7 @@ import { EXACT_SCHEME, PaymentRequirements, PaymentRequirementsSchema, + DeferredEscrowDepositAuthorizationConfig, } from "x402/types"; /** @@ -119,7 +121,12 @@ export function withPaymentInterceptor( * * @param axiosClient - The Axios instance to add the interceptor to * @param walletClient - A wallet client that can sign transactions and create payment headers + * @param autoDepositConfigs - A list of deposit configurations to use for the deferred payment protocol deposit with authorization flow + * - asset: The asset to deposit + * - threshold: The threshold at which to deposit + * - depositAmount: The amount to deposit * @param paymentRequirementsSelector - A function that selects the payment requirements from the response + * * @returns The modified Axios instance with the payment interceptor * * @example @@ -136,6 +143,7 @@ export function withPaymentInterceptor( export function withDeferredPaymentInterceptor( axiosClient: AxiosInstance, walletClient: Signer | MultiNetworkSigner, + autoDepositConfigs: DeferredEscrowDepositAuthorizationConfig[] = [], paymentRequirementsSelector: PaymentRequirementsSelector = selectPaymentRequirements, ) { // intercept the request to send a `X-PAYMENT-BUYER` header with each request @@ -185,15 +193,19 @@ export function withDeferredPaymentInterceptor( network, DEFERRRED_SCHEME, ); - console.log(selectedPaymentRequirements); const selectedDeferredPaymentRequirements = DeferredPaymentRequirementsSchema.parse( selectedPaymentRequirements, ); - + const extraPayload = await deferred.evm.createPaymentExtraPayload( + walletClient as typeof evm.EvmSigner, + selectedDeferredPaymentRequirements, + autoDepositConfigs, + ); const paymentHeader = await createPaymentHeader( walletClient, x402Version, selectedDeferredPaymentRequirements, + extraPayload, ); (originalConfig as { __is402Retry?: boolean }).__is402Retry = true; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index 3a05c1b077..429f05f42b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -1,9 +1,12 @@ -import { Address, Chain, getAddress, Hex, LocalAccount, Transport } from "viem"; +import { Address, Chain, Client, getAddress, Hex, LocalAccount, toHex, Transport } from "viem"; import { getNetworkId } from "../../../shared/network"; import { isSignerWallet, SignerWallet } from "../../../types/shared/evm"; import { PaymentPayload, PaymentRequirements, UnsignedPaymentPayload } from "../../../types/verify"; import { + DeferredEscrowDepositAuthorization, + DeferredEscrowDepositAuthorizationConfig, DeferredEscrowDepositAuthorizationSchema, + DeferredEscrowDepositAuthorizationSignedPermit, DeferredEvmPayloadVoucher, DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, DeferredEvmPaymentRequirementsExtraNewVoucherSchema, @@ -12,8 +15,10 @@ import { UnsignedDeferredPaymentPayload, UnsignedDeferredPaymentPayloadSchema, } from "../../../types/verify/schemes/deferred"; -import { signVoucher, verifyVoucher } from "./sign"; +import { signPermit, signDepositAuthorizationInner, signVoucher, verifyVoucher } from "./sign"; import { encodePayment } from "./utils/paymentUtils"; +import { getUsdcChainConfigForChain } from "../../../shared/evm"; +import { randomBytes } from "node:crypto"; const EXPIRY_TIME = 60 * 60 * 24 * 30; // 30 days @@ -208,3 +213,113 @@ export async function createPaymentHeader( const payment = await createPayment(client, x402Version, paymentRequirements, extraPayload); return encodePayment(payment); } + +/** + * Creates the payment extra payload for deferred scheme with deposit with authorization flow. + * + * __Note__: This implementation requires the buyer to trust the seller provided balance to decide if they deposit additional + * funds to the escrow. A malicious seller could manipulate the value and force additional deposits from the buyer, those funds + * would not be at risk as they could be withdrawn, however it would be a form of abuse. + * TODO: We could improve this by having this client-side function verify the balance themselves, that requires however the client + * to make a direct call to the facilitator. + * + * @param client - The signer wallet instance used to create the payment extra payload + * @param paymentRequirements - The payment requirements containing scheme and network information + * @param depositConfigs - The auto deposit configurations to use for the deposit with authorization flow + * @returns The extra payload or undefined + */ +export async function createPaymentExtraPayload( + client: SignerWallet | LocalAccount, + paymentRequirements: PaymentRequirements, + depositConfigs: DeferredEscrowDepositAuthorizationConfig[], +): Promise { + const { network, asset, extra, maxAmountRequired } = + DeferredPaymentRequirementsSchema.parse(paymentRequirements); + const buyer = (client as LocalAccount).address || (client as Client).account?.address; + + // No account info, no deposit + if (extra.account === undefined) { + return; + } + + let depositConfig = depositConfigs.find(config => getAddress(config.asset) === getAddress(asset)); + + if (depositConfig === undefined) { + const chainId = getNetworkId(network); + const usdc = getUsdcChainConfigForChain(chainId); + + // No matching asset, no deposit + if (usdc === undefined) { + return; + } + + depositConfig = { + asset: usdc.usdcAddress, + assetDomain: { + name: usdc.usdcName, + version: "2", // TODO: use getVersion + }, + threshold: "10000", // 0.01 USDC + amount: "1000000", // 1 USDC + }; + } + + // Enough balance, no deposit + if ( + BigInt(extra.account.balance) >= + BigInt(depositConfig.threshold) + BigInt(maxAmountRequired) + ) { + return; + } + + // Build ERC20 permit if needed + let signedErc20Permit: DeferredEscrowDepositAuthorizationSignedPermit | undefined; + if (BigInt(extra.account.assetAllowance) < BigInt(depositConfig.amount)) { + const erc20Permit = { + nonce: extra.account.assetPermitNonce, + value: depositConfig.amount, + domain: { + name: depositConfig.assetDomain.name, + version: depositConfig.assetDomain.version, + }, + owner: getAddress(buyer), + spender: getAddress(extra.voucher.escrow), + deadline: Math.floor(Date.now() / 1000) + EXPIRY_TIME, + }; + const erc20PermitSignature = await signPermit( + client, + erc20Permit, + getNetworkId(network), + getAddress(asset), + ); + signedErc20Permit = { + ...erc20Permit, + signature: erc20PermitSignature.signature, + }; + } + + // Build deposit authorization + const depositAuthorization = { + buyer: getAddress(buyer), + seller: getAddress(paymentRequirements.payTo), + asset: getAddress(asset), + amount: depositConfig.amount, + nonce: toHex(randomBytes(32)), + expiry: Math.floor(Date.now() / 1000) + EXPIRY_TIME, + }; + + const depositAuthorizationSignature = await signDepositAuthorizationInner( + client, + depositAuthorization, + getNetworkId(network), + getAddress(extra.voucher.escrow), + ); + + return { + ...(signedErc20Permit && { permit: signedErc20Permit }), + depositAuthorization: { + ...depositAuthorization, + signature: depositAuthorizationSignature.signature, + }, + }; +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 7c32793492..126abe7e18 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -17,6 +17,9 @@ import { VerifyResponse, } from "../../../types/verify"; import { + DeferredAccountDetailsResponse, + DeferredDepositWithAuthorizationResponse, + DeferredErrorResponse, DeferredEscrowDepositAuthorization, DeferredEvmPayloadVoucher, DeferredPaymentPayloadSchema, @@ -335,7 +338,7 @@ export async function depositWithAuthorization, voucher: DeferredEvmPayloadVoucher, depositAuthorization: DeferredEscrowDepositAuthorization, -): Promise { +): Promise { // Verify the deposit authorization const valid = await verifyDepositAuthorization(wallet, voucher, depositAuthorization); if (!valid.isValid) { @@ -443,7 +446,7 @@ export async function depositWithAuthorization { +): Promise { const outstandingVouchers = await voucherStore.getVouchers( { buyer, @@ -482,12 +485,14 @@ export async function getEscrowAccountBalance< }, ); - let buyerAccountBalance: bigint; + let balance: bigint; + let allowance: bigint; + let nonce: bigint; try { - buyerAccountBalance = await client.readContract({ + [balance, allowance, nonce] = await client.readContract({ address: escrow as Address, abi: deferredEscrowABI, - functionName: "getAccountBalance", + functionName: "getAccountDetails", args: [ buyer as Address, seller as Address, @@ -499,9 +504,13 @@ export async function getEscrowAccountBalance< } catch (error) { console.log(error); return { - error: "invalid_deferred_evm_contract_call_failed_account", + error: "invalid_deferred_evm_contract_call_failed_account_details", }; } - return buyerAccountBalance; + return { + balance: balance.toString(), + assetAllowance: allowance.toString(), + assetPermitNonce: nonce.toString(), + }; } diff --git a/typescript/packages/x402/src/schemes/deferred/evm/server.ts b/typescript/packages/x402/src/schemes/deferred/evm/server.ts index aed4090b8d..d6386b4fdc 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/server.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/server.ts @@ -35,10 +35,10 @@ export async function getPaymentRequirementsExtra( seller: string, ) => Promise, ): Promise { - const { getEscrowAccountBalance } = useDeferredFacilitator(facilitator); + const { getEscrowAccountDetails } = useDeferredFacilitator(facilitator); let buyer: Address; - const newVoucherExtra = { + const newVoucherExtra: PaymentRequirementsExtra = { type: "new" as const, voucher: { id: generateVoucherId(), @@ -63,27 +63,40 @@ export async function getPaymentRequirementsExtra( buyer = xBuyerHeader!; // This is safe due to the previous early return } - // Retrieve balance from facilitator -- if it fails return 0n which means the depositWithAuth flow will not be triggered - let balance = 0n; + // Retrieve account details from facilitator + let balance = ""; + let assetAllowance = ""; + let assetPermitNonce = ""; + let success = false; try { - balance = await getEscrowAccountBalance(buyer, seller, asset, escrow, chainId); + const response = await getEscrowAccountDetails(buyer, seller, asset, escrow, chainId); + if (!("error" in response)) { + success = true; + ({ balance, assetAllowance, assetPermitNonce } = response); + } } catch (error) { console.error(error); } + const account = { + balance, + assetAllowance, + assetPermitNonce, + facilitator: facilitator.url, + }; + const previousVoucher = await getAvailableVoucher(buyer, seller); if (previousVoucher) { return { type: "aggregation" as const, - balance: { - balance: balance.toString(), - facilitator: facilitator.url, - }, + ...(success ? { account } : {}), signature: previousVoucher.signature, voucher: { ...previousVoucher, }, }; } + + if (success) newVoucherExtra.account = account; return newVoucherExtra; } diff --git a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts index c96bffaaa0..44544fc9e1 100644 --- a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts +++ b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts @@ -264,7 +264,7 @@ export const deferredEscrowABI = [ }, { type: "function", - name: "getAccountBalance", + name: "getAccountDetails", inputs: [ { name: "buyer", type: "address", internalType: "address" }, { name: "seller", type: "address", internalType: "address" }, @@ -272,7 +272,11 @@ export const deferredEscrowABI = [ { name: "voucherIds", type: "bytes32[]", internalType: "bytes32[]" }, { name: "valueAggregates", type: "uint256[]", internalType: "uint256[]" }, ], - outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + outputs: [ + { name: "", type: "uint256", internalType: "uint256" }, + { name: "", type: "uint256", internalType: "uint256" }, + { name: "", type: "uint256", internalType: "uint256" }, + ], stateMutability: "view", }, { diff --git a/typescript/packages/x402/src/types/verify/refiners.ts b/typescript/packages/x402/src/types/verify/refiners.ts index 3846c41786..a53ad294b4 100644 --- a/typescript/packages/x402/src/types/verify/refiners.ts +++ b/typescript/packages/x402/src/types/verify/refiners.ts @@ -1,3 +1,4 @@ // Refiners export const isInteger = (value: string) => Number.isInteger(Number(value)) && Number(value) >= 0; +export const isBigInt = (value: string) => BigInt(value) >= 0n; export const hasMaxLength = (maxLength: number) => (value: string) => value.length <= maxLength; diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 8705acf9ec..6d7884a807 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -6,9 +6,11 @@ import { EvmMaxAtomicUnits, EvmTransactionHashRegex, } from "../constants"; -import { hasMaxLength, isInteger } from "../refiners"; +import { hasMaxLength, isBigInt, isInteger } from "../refiners"; import { BasePaymentPayloadSchema, BasePaymentRequirementsSchema } from "./base"; import { VoucherStore } from "../../../schemes/deferred/evm/store"; +import { ErrorReasons } from "../x402Specs"; +import { EvmOrSvmAddress, MixedAddressRegex, NetworkSchema } from "../.."; export const DEFERRRED_SCHEME = "deferred"; @@ -95,7 +97,7 @@ export const DeferredEscrowDepositAuthorizationPermitSchema = z.object({ owner: z.string().regex(EvmAddressRegex), spender: z.string().regex(EvmAddressRegex), value: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), - nonce: z.number().int().nonnegative(), + nonce: z.string().refine(isBigInt), deadline: z.number().int().nonnegative(), domain: z.object({ name: z.string(), @@ -146,6 +148,20 @@ export type DeferredEscrowDepositAuthorization = z.infer< typeof DeferredEscrowDepositAuthorizationSchema >; +// x402DeferredEscrowDepositAuthorizationConfig +export const DeferredEscrowDepositAuthorizationConfigSchema = z.object({ + asset: z.string().regex(EvmAddressRegex), + assetDomain: z.object({ + name: z.string(), + version: z.string(), + }), + threshold: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + amount: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), +}); +export type DeferredEscrowDepositAuthorizationConfig = z.infer< + typeof DeferredEscrowDepositAuthorizationConfigSchema +>; + // x402DeferredEvmPayload export const DeferredEvmPayloadSchema = z.object({ signature: z.string().regex(EvmSignatureRegex), @@ -171,18 +187,20 @@ export const UnsignedDeferredPaymentPayloadSchema = BasePaymentPayloadSchema.ext export type UnsignedDeferredPaymentPayload = z.infer; // x402DeferredEvmPaymentRequirementsExtraAccountBalance -export const DeferredEvmPaymentRequirementsExtraAccountBalanceSchema = z.object({ +export const DeferredEvmPaymentRequirementsExtraAccountDetailsSchema = z.object({ balance: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + assetAllowance: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + assetPermitNonce: z.string().refine(isBigInt), facilitator: z.string(), }); -export type DeferredEvmPaymentRequirementsExtraAccountBalance = z.infer< - typeof DeferredEvmPaymentRequirementsExtraAccountBalanceSchema +export type DeferredEvmPaymentRequirementsExtraAccountDetails = z.infer< + typeof DeferredEvmPaymentRequirementsExtraAccountDetailsSchema >; // x402DeferredEvmPaymentRequirementsExtraNewVoucher export const DeferredEvmPaymentRequirementsExtraNewVoucherSchema = z.object({ type: z.literal("new"), - balance: DeferredEvmPaymentRequirementsExtraAccountBalanceSchema.optional(), + account: DeferredEvmPaymentRequirementsExtraAccountDetailsSchema.optional(), voucher: DeferredEvmPayloadVoucherSchema.pick({ id: true, escrow: true }), }); export type DeferredEvmPaymentRequirementsExtraNewVoucher = z.infer< @@ -192,7 +210,7 @@ export type DeferredEvmPaymentRequirementsExtraNewVoucher = z.infer< // x402DeferredEvmPaymentRequirementsExtraAggregationVoucher export const DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema = z.object({ type: z.literal("aggregation"), - balance: DeferredEvmPaymentRequirementsExtraAccountBalanceSchema.optional(), + account: DeferredEvmPaymentRequirementsExtraAccountDetailsSchema.optional(), signature: z.string().regex(EvmSignatureRegex), voucher: DeferredEvmPayloadVoucherSchema, }); @@ -273,3 +291,23 @@ export const DeferredVoucherCollectionsResponseSchema = z.union([ export type DeferredVoucherCollectionsResponse = z.infer< typeof DeferredVoucherCollectionsResponseSchema >; + +// x402DeferredDepositWithAuthorizationResponse +export const DeferredDepositWithAuthorizationResponseSchema = z.object({ + success: z.boolean(), + errorReason: z.enum(ErrorReasons).optional(), + payer: EvmOrSvmAddress.optional(), + transaction: z.string().regex(MixedAddressRegex), + network: NetworkSchema.optional(), +}); +export type DeferredDepositWithAuthorizationResponse = z.infer< + typeof DeferredDepositWithAuthorizationResponseSchema +>; + +// x402DeferredAccountDetailsResponse +export const DeferredAccountDetailsResponseSchema = z.object({ + balance: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + assetAllowance: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), + assetPermitNonce: z.string().refine(isBigInt), +}); +export type DeferredAccountDetailsResponse = z.infer; diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index 65d28cff77..a7c444f1c6 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -1,5 +1,6 @@ import { toJsonSafe } from "../shared/json"; import { + DeferredAccountDetailsResponse, DeferredErrorResponse, DeferredVoucherCollectionsResponse, DeferredVoucherResponse, @@ -281,7 +282,7 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { } /** - * Fetches the balance of an escrow account + * Fetches the details of an escrow account for a given buyer, seller, and asset * * @param buyer - The buyer address * @param seller - The seller address @@ -290,21 +291,23 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { * @param chainId - The chain ID * @returns The balance of the escrow account */ - async function getEscrowAccountBalance( + async function getEscrowAccountDetails( buyer: string, seller: string, asset: string, escrow: string, chainId: number, - ): Promise { + ): Promise { const response = await fetch( `${facilitator.url}/deferred/accounts?buyer=${buyer}&seller=${seller}&asset=${asset}&escrow=${escrow}&chainId=${chainId}`, ); - const responseJson = (await response.json()) as { balance: string } | { error: string }; + const responseJson = (await response.json()) as + | DeferredAccountDetailsResponse + | DeferredErrorResponse; if ("error" in responseJson) { throw new Error(responseJson.error); } - return BigInt(responseJson.balance); + return responseJson; } return { @@ -316,6 +319,6 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { verifyVoucher, settleVoucher, getVoucherCollections, - getEscrowAccountBalance, + getEscrowAccountDetails, }; } From 6bad2eef26c49dbf90446fbf8e83db182233f97e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 13 Oct 2025 17:27:10 -0300 Subject: [PATCH 093/116] feat(deferred): client verify balance before signing deposit auth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/schemes/deferred/evm/client.ts | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index 429f05f42b..b5eb9f9b30 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -19,6 +19,7 @@ import { signPermit, signDepositAuthorizationInner, signVoucher, verifyVoucher } import { encodePayment } from "./utils/paymentUtils"; import { getUsdcChainConfigForChain } from "../../../shared/evm"; import { randomBytes } from "node:crypto"; +import { useDeferredFacilitator } from "../../../verify/useDeferred"; const EXPIRY_TIME = 60 * 60 * 24 * 30; // 30 days @@ -272,11 +273,35 @@ export async function createPaymentExtraPayload( return; } + // Ensure the deposit is actually needed + // This creates a client/buyer <> facilitator interaction but it's necessary to avoid having to trust the seller + const { getEscrowAccountDetails } = useDeferredFacilitator({ + url: extra.account.facilitator as `${string}://${string}`, + }); + const accountDetails = await getEscrowAccountDetails( + buyer, + paymentRequirements.payTo, + asset, + extra.voucher.escrow, + getNetworkId(network), + ); + if ("error" in accountDetails) { + return; + } + + // Re-check balance using the data obtained from the facilitator + if ( + BigInt(accountDetails.balance) >= + BigInt(depositConfig.threshold) + BigInt(maxAmountRequired) + ) { + return; + } + // Build ERC20 permit if needed let signedErc20Permit: DeferredEscrowDepositAuthorizationSignedPermit | undefined; - if (BigInt(extra.account.assetAllowance) < BigInt(depositConfig.amount)) { + if (BigInt(accountDetails.assetAllowance) < BigInt(depositConfig.amount)) { const erc20Permit = { - nonce: extra.account.assetPermitNonce, + nonce: accountDetails.assetPermitNonce, value: depositConfig.amount, domain: { name: depositConfig.assetDomain.name, From 4d1854d3b3d32a0628ab23959c72307608e021f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 13 Oct 2025 18:12:49 -0300 Subject: [PATCH 094/116] test: fix deferred tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/client.test.ts | 2 +- .../src/schemes/deferred/evm/facilitator.ts | 3 +- .../schemes/deferred/evm/integration.test.ts | 17 ++++++- .../src/schemes/deferred/evm/server.test.ts | 50 ++++++++++++++++++- .../deferred/evm/utils/paymentUtils.test.ts | 2 +- .../src/schemes/deferred/evm/verify.test.ts | 2 +- .../x402/src/types/verify/schemes/deferred.ts | 11 ++-- .../x402/src/types/verify/x402Specs.ts | 1 - 8 files changed, 74 insertions(+), 14 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts index a32f156474..2931c23bbe 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -119,7 +119,7 @@ describe("preparePaymentHeader: new voucher", () => { owner: buyerAddress, spender: escrowAddress, value: "1000000", - nonce: 0, + nonce: "0", deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, domain: { name: "USD Coin", diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 126abe7e18..9069b67573 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -16,6 +16,7 @@ import { SettleResponse, VerifyResponse, } from "../../../types/verify"; +import { ErrorReasons } from "../../../types/verify/x402Specs"; import { DeferredAccountDetailsResponse, DeferredDepositWithAuthorizationResponse, @@ -167,7 +168,7 @@ export async function settle( network: paymentPayload.network, transaction: "", errorReason: - depositAuthorizationResponse.errorReason ?? + (depositAuthorizationResponse.errorReason as (typeof ErrorReasons)[number]) ?? "invalid_deferred_evm_payload_deposit_authorization_failed", payer: paymentPayload.payload.voucher.buyer, }; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts index cee8249117..9f83091974 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts @@ -82,6 +82,9 @@ describe("Deferred Payment Integration Tests", () => { buyerAddress, sellerAddress, escrowAddress, + assetAddress, + 84532, + { url: "https://facilitator.x402.io" }, (buyer, seller) => voucherStore.getAvailableVoucher(buyer, seller), ), } as DeferredPaymentRequirements; @@ -176,6 +179,9 @@ describe("Deferred Payment Integration Tests", () => { buyerAddress, sellerAddress, escrowAddress, + assetAddress, + 84532, + { url: "https://facilitator.x402.io" }, (buyer, seller) => voucherStore.getAvailableVoucher(buyer, seller), ), } as DeferredPaymentRequirements; @@ -271,6 +277,9 @@ describe("Deferred Payment Integration Tests", () => { buyerAddress, sellerAddress, escrowAddress, + assetAddress, + 84532, + { url: "https://facilitator.x402.io" }, (buyer, seller) => voucherStore.getAvailableVoucher(buyer, seller), ), } as DeferredPaymentRequirements; @@ -289,6 +298,9 @@ describe("Deferred Payment Integration Tests", () => { undefined, // no X-BUYER header sellerAddress, escrowAddress, + assetAddress, + 84532, + { url: "https://facilitator.x402.io" }, (buyer, seller) => voucherStore.getAvailableVoucher(buyer, seller), ), } as DeferredPaymentRequirements; @@ -385,7 +397,7 @@ describe("Deferred Payment Integration Tests", () => { owner: buyerAddress, spender: escrowAddress, value: depositAmount, - nonce: 0, + nonce: "0", deadline: now + oneWeek * 2, domain: { name: "USD Coin", @@ -430,6 +442,9 @@ describe("Deferred Payment Integration Tests", () => { buyerAddress, sellerAddress, escrowAddress, + assetAddress, + 84532, + { url: "https://facilitator.x402.io" }, (buyer, seller) => voucherStore.getAvailableVoucher(buyer, seller), ), } as DeferredPaymentRequirements; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/server.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/server.test.ts index 450c73179c..d0c4cbdb73 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/server.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/server.test.ts @@ -8,6 +8,7 @@ import { import { getPaymentRequirementsExtra } from "./server"; import * as idModule from "./id"; import * as paymentUtilsModule from "./utils/paymentUtils"; +import * as useDeferredModule from "../../../verify/useDeferred"; // Mock dependencies vi.mock("./id", () => ({ @@ -18,10 +19,16 @@ vi.mock("./utils/paymentUtils", () => ({ decodePayment: vi.fn(), })); +vi.mock("../../../verify/useDeferred", () => ({ + useDeferredFacilitator: vi.fn(), +})); + describe("getPaymentRequirementsExtra", () => { const mockSeller: Address = "0x1234567890123456789012345678901234567890"; const mockEscrow: Address = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"; const mockBuyer: Address = "0x9876543210987654321098765432109876543210"; + const mockAsset: Address = "0x1111111111111111111111111111111111111111"; + const mockChainId = 84532; const mockVoucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; const mockSignature = "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c"; @@ -31,20 +38,26 @@ describe("getPaymentRequirementsExtra", () => { buyer: mockBuyer, seller: mockSeller, valueAggregate: "1000000", - asset: "0x1111111111111111111111111111111111111111", + asset: mockAsset, timestamp: 1715769600, nonce: 5, escrow: mockEscrow, - chainId: 84532, + chainId: mockChainId, expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, signature: mockSignature, }; const mockGetAvailableVoucher = vi.fn(); + const mockGetEscrowAccountDetails = vi.fn(); beforeEach(() => { vi.clearAllMocks(); vi.mocked(idModule.generateVoucherId).mockReturnValue(mockVoucherId); + vi.mocked(useDeferredModule.useDeferredFacilitator).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + } as unknown as ReturnType); + // Mock getEscrowAccountDetails to return an error by default (so it doesn't add account info) + mockGetEscrowAccountDetails.mockResolvedValue({ error: "not available" }); }); describe("when no headers are provided", () => { @@ -54,6 +67,9 @@ describe("getPaymentRequirementsExtra", () => { undefined, mockSeller, mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, mockGetAvailableVoucher, ); @@ -79,6 +95,9 @@ describe("getPaymentRequirementsExtra", () => { mockBuyer, mockSeller, mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, mockGetAvailableVoucher, ); @@ -100,6 +119,9 @@ describe("getPaymentRequirementsExtra", () => { mockBuyer, mockSeller, mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, mockGetAvailableVoucher, ); @@ -136,6 +158,9 @@ describe("getPaymentRequirementsExtra", () => { undefined, mockSeller, mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, mockGetAvailableVoucher, ); @@ -164,6 +189,9 @@ describe("getPaymentRequirementsExtra", () => { undefined, mockSeller, mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, mockGetAvailableVoucher, ); @@ -197,6 +225,9 @@ describe("getPaymentRequirementsExtra", () => { undefined, mockSeller, mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, mockGetAvailableVoucher, ); @@ -240,6 +271,9 @@ describe("getPaymentRequirementsExtra", () => { mockBuyer, // This should be ignored mockSeller, mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, mockGetAvailableVoucher, ); @@ -269,6 +303,9 @@ describe("getPaymentRequirementsExtra", () => { mockBuyer, mockSeller, mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, mockGetAvailableVoucher, ), ).rejects.toThrow("Database error"); @@ -285,6 +322,9 @@ describe("getPaymentRequirementsExtra", () => { undefined, mockSeller, mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, mockGetAvailableVoucher, ), ).rejects.toThrow("Invalid base64"); @@ -303,6 +343,9 @@ describe("getPaymentRequirementsExtra", () => { undefined, mockSeller, mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, mockGetAvailableVoucher, )) as DeferredPaymentRequirements["extra"]; @@ -311,6 +354,9 @@ describe("getPaymentRequirementsExtra", () => { undefined, mockSeller, mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, mockGetAvailableVoucher, )) as DeferredPaymentRequirements["extra"]; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts index 08ff41082b..8765045d0a 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/utils/paymentUtils.test.ts @@ -258,7 +258,7 @@ describe("paymentUtils", () => { owner: buyerAddress, spender: escrowAddress, value: "1000000", - nonce: 0, + nonce: "0", deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, domain: { name: "USD Coin", diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts index 46673f7746..051c83a631 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts @@ -1233,7 +1233,7 @@ describe("verifyDepositAuthorization", () => { owner: buyerAddress, spender: escrowAddress, value: "1000000", - nonce: 0, + nonce: "0", deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, domain: { name: "USD Coin", diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 6d7884a807..5b45ea693a 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -9,8 +9,7 @@ import { import { hasMaxLength, isBigInt, isInteger } from "../refiners"; import { BasePaymentPayloadSchema, BasePaymentRequirementsSchema } from "./base"; import { VoucherStore } from "../../../schemes/deferred/evm/store"; -import { ErrorReasons } from "../x402Specs"; -import { EvmOrSvmAddress, MixedAddressRegex, NetworkSchema } from "../.."; +import { NetworkSchema } from "../../shared/network"; export const DEFERRRED_SCHEME = "deferred"; @@ -266,7 +265,7 @@ export type DeferredVouchersResponse = z.infer Date: Tue, 14 Oct 2025 09:56:05 -0300 Subject: [PATCH 095/116] test: fix tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-axios/src/index.test.ts | 14 ++++++++++++++ .../src/schemes/deferred/evm/facilitator.test.ts | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/typescript/packages/x402-axios/src/index.test.ts b/typescript/packages/x402-axios/src/index.test.ts index 3d33963978..ee7d49a3ab 100644 --- a/typescript/packages/x402-axios/src/index.test.ts +++ b/typescript/packages/x402-axios/src/index.test.ts @@ -25,6 +25,14 @@ vi.mock("x402/client", () => ({ selectPaymentRequirements: vi.fn(), })); +vi.mock("x402/schemes", () => ({ + deferred: { + evm: { + createPaymentExtraPayload: vi.fn(), + }, + }, +})); + const createErrorConfig = ( isRetry = false, headers = new AxiosHeaders(), @@ -324,16 +332,21 @@ describe("withDeferredPaymentInterceptor", () => { it("should handle 402 errors and retry with payment header", async () => { const paymentHeader = "payment-header-value"; + const extraPayload = { some: "payload" }; const successResponse = { data: "success", headers: new AxiosHeaders().set("X-PAYMENT-BUYER", mockWalletClient.address), } as AxiosResponse; const { createPaymentHeader, selectPaymentRequirements } = await import("x402/client"); + const { deferred } = await import("x402/schemes"); (createPaymentHeader as ReturnType).mockResolvedValue(paymentHeader); (selectPaymentRequirements as ReturnType).mockImplementation( (requirements, _) => requirements[0], ); + (deferred.evm.createPaymentExtraPayload as ReturnType).mockResolvedValue( + extraPayload, + ); (mockAxiosClient.request as ReturnType).mockResolvedValue(successResponse); const error = createAxiosError(402, createErrorConfig(false), { @@ -353,6 +366,7 @@ describe("withDeferredPaymentInterceptor", () => { mockWalletClient, 1, validPaymentRequirements[0], + extraPayload, ); const actualCall = (mockAxiosClient.request as ReturnType).mock.calls[0][0]; diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts index 40d44f1c0f..33a237f9f2 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts @@ -601,7 +601,7 @@ describe("facilitator - depositWithAuthorization", () => { owner: buyerAddress, spender: escrowAddress, value: "1000000", - nonce: 0, + nonce: "0", deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, domain: { name: "USD Coin", From de2f5575e150377fd3039cace3dcbd2494010d27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 14 Oct 2025 16:16:04 -0300 Subject: [PATCH 096/116] test: add more tests for deposit with auth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/client.test.ts | 343 ++++++++++++++ .../schemes/deferred/evm/facilitator.test.ts | 312 ++++++++++++- .../schemes/deferred/evm/integration.test.ts | 436 +++++++++++++++++- .../x402/src/schemes/deferred/evm/verify.ts | 2 +- 4 files changed, 1089 insertions(+), 4 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts index 2931c23bbe..eb7f35b5d9 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -6,6 +6,7 @@ import { preparePaymentHeader, signPaymentHeader, createNewVoucher, + createPaymentExtraPayload, } from "./client"; import { DeferredEvmPaymentRequirementsExtraAggregationVoucherSchema, @@ -19,6 +20,10 @@ vi.mock("./utils/paymentUtils", () => ({ encodePayment: vi.fn().mockReturnValue("encoded-payment-header"), })); +vi.mock("../../../verify/useDeferred", () => ({ + useDeferredFacilitator: vi.fn(), +})); + const buyer = createSigner( "base-sepolia", "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", @@ -620,3 +625,341 @@ describe("createPaymentHeader", () => { ); }); }); + +describe("createPaymentExtraPayload", () => { + const mockPaymentRequirements: PaymentRequirements = { + scheme: "deferred", + network: "base-sepolia", + maxAmountRequired: "1000000", + resource: "https://example.com/resource", + description: "Test resource", + mimeType: "application/json", + payTo: sellerAddress, + maxTimeoutSeconds: 300, + asset: assetAddress, + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + account: { + balance: "500000", // Below threshold + assetAllowance: "0", + assetPermitNonce: "0", + facilitator: "https://facilitator.example.com", + }, + }, + }; + + const mockDepositConfig = { + asset: assetAddress, + assetDomain: { + name: "USD Coin", + version: "2", + }, + threshold: "10000", + amount: "1000000", + }; + + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2024-05-20T00:00:00Z")); + vi.clearAllMocks(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it("should return undefined when extra.account is undefined", async () => { + const paymentReqs = { + ...mockPaymentRequirements, + extra: { + type: "new", + voucher: { + id: voucherId, + escrow: escrowAddress, + }, + }, + } as PaymentRequirements; + + const result = await createPaymentExtraPayload(buyer, paymentReqs, [mockDepositConfig]); + expect(result).toBeUndefined(); + }); + + it("should return undefined when balance is sufficient", async () => { + const paymentReqs = { + ...mockPaymentRequirements, + extra: { + ...mockPaymentRequirements.extra, + account: { + balance: "10000000", // High balance + assetAllowance: "1000000", + assetPermitNonce: "0", + facilitator: "https://facilitator.example.com", + }, + }, + } as PaymentRequirements; + + const result = await createPaymentExtraPayload(buyer, paymentReqs, [mockDepositConfig]); + expect(result).toBeUndefined(); + }); + + it("should return undefined when facilitator check shows sufficient balance", async () => { + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + balance: "10000000", // High balance from facilitator + assetAllowance: "1000000", + assetPermitNonce: "0", + }); + + vi.mocked(useDeferredFacilitator).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + const result = await createPaymentExtraPayload(buyer, mockPaymentRequirements, [ + mockDepositConfig, + ]); + + expect(mockGetEscrowAccountDetails).toHaveBeenCalledWith( + buyerAddress, + sellerAddress, + assetAddress, + escrowAddress, + 84532, + ); + expect(result).toBeUndefined(); + }); + + it("should return undefined when facilitator returns error", async () => { + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + error: "facilitator_error", + }); + + vi.mocked(useDeferredFacilitator).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + const result = await createPaymentExtraPayload(buyer, mockPaymentRequirements, [ + mockDepositConfig, + ]); + + expect(result).toBeUndefined(); + }); + + it("should create deposit authorization with permit when allowance is insufficient", async () => { + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + balance: "500000", // Low balance + assetAllowance: "0", // No allowance + assetPermitNonce: "5", + }); + + vi.mocked(useDeferredFacilitator).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + const result = await createPaymentExtraPayload(buyer, mockPaymentRequirements, [ + mockDepositConfig, + ]); + + expect(result).toBeDefined(); + expect(result?.permit).toBeDefined(); + expect(result?.permit?.owner).toBe(buyerAddress); + expect(result?.permit?.spender).toBe(escrowAddress); + expect(result?.permit?.value).toBe("1000000"); + expect(result?.permit?.nonce).toBe("5"); + expect(result?.permit?.deadline).toBe(Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30); + expect(result?.permit?.domain).toEqual({ + name: "USD Coin", + version: "2", + }); + expect(result?.permit?.signature).toBeDefined(); + + expect(result?.depositAuthorization).toBeDefined(); + expect(result?.depositAuthorization.buyer).toBe(buyerAddress); + expect(result?.depositAuthorization.seller).toBe(sellerAddress); + expect(result?.depositAuthorization.asset).toBe(assetAddress); + expect(result?.depositAuthorization.amount).toBe("1000000"); + expect(result?.depositAuthorization.nonce).toMatch(/^0x[0-9a-f]{64}$/); + expect(result?.depositAuthorization.expiry).toBe( + Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30, + ); + expect(result?.depositAuthorization.signature).toBeDefined(); + }); + + it("should create deposit authorization without permit when allowance is sufficient", async () => { + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + balance: "500000", // Low balance + assetAllowance: "2000000", // Sufficient allowance + assetPermitNonce: "5", + }); + + vi.mocked(useDeferredFacilitator).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + const result = await createPaymentExtraPayload(buyer, mockPaymentRequirements, [ + mockDepositConfig, + ]); + + expect(result).toBeDefined(); + expect(result?.permit).toBeUndefined(); // No permit needed + expect(result?.depositAuthorization).toBeDefined(); + expect(result?.depositAuthorization.buyer).toBe(buyerAddress); + expect(result?.depositAuthorization.seller).toBe(sellerAddress); + expect(result?.depositAuthorization.asset).toBe(assetAddress); + expect(result?.depositAuthorization.amount).toBe("1000000"); + expect(result?.depositAuthorization.signature).toBeDefined(); + }); + + it("should use default USDC config when no matching deposit config is provided", async () => { + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + balance: "500000", + assetAllowance: "2000000", + assetPermitNonce: "0", + }); + + vi.mocked(useDeferredFacilitator).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + const usdcPaymentReqs = { + ...mockPaymentRequirements, + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", // Base Sepolia USDC + } as PaymentRequirements; + + const result = await createPaymentExtraPayload(buyer, usdcPaymentReqs, []); + + expect(result).toBeDefined(); + expect(result?.depositAuthorization.amount).toBe("1000000"); // Default 1 USDC + }); + + it("should handle balance exactly at threshold plus maxAmountRequired", async () => { + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + balance: "1010000", // Exactly threshold (10000) + maxAmountRequired (1000000) + assetAllowance: "2000000", + assetPermitNonce: "0", + }); + + vi.mocked(useDeferredFacilitator).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + const result = await createPaymentExtraPayload(buyer, mockPaymentRequirements, [ + mockDepositConfig, + ]); + + expect(result).toBeUndefined(); // Should not need deposit + }); + + it("should create deposit when balance is one unit below threshold plus maxAmountRequired", async () => { + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + balance: "1009999", // One below threshold (10000) + maxAmountRequired (1000000) + assetAllowance: "2000000", + assetPermitNonce: "0", + }); + + vi.mocked(useDeferredFacilitator).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + const result = await createPaymentExtraPayload(buyer, mockPaymentRequirements, [ + mockDepositConfig, + ]); + + expect(result).toBeDefined(); + expect(result?.depositAuthorization).toBeDefined(); + }); + + it("should use custom deposit config when provided", async () => { + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + balance: "500000", + assetAllowance: "0", + assetPermitNonce: "10", + }); + + vi.mocked(useDeferredFacilitator).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + const customDepositConfig = { + asset: assetAddress, + assetDomain: { + name: "Custom Token", + version: "1", + }, + threshold: "50000", + amount: "5000000", + }; + + const result = await createPaymentExtraPayload(buyer, mockPaymentRequirements, [ + customDepositConfig, + ]); + + expect(result).toBeDefined(); + expect(result?.depositAuthorization.amount).toBe("5000000"); + expect(result?.permit?.value).toBe("5000000"); + expect(result?.permit?.domain).toEqual({ + name: "Custom Token", + version: "1", + }); + }); + + it("should handle allowance exactly at deposit amount", async () => { + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + balance: "500000", + assetAllowance: "1000000", // Exactly the deposit amount + assetPermitNonce: "0", + }); + + vi.mocked(useDeferredFacilitator).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + const result = await createPaymentExtraPayload(buyer, mockPaymentRequirements, [ + mockDepositConfig, + ]); + + expect(result).toBeDefined(); + expect(result?.permit).toBeUndefined(); // Allowance is sufficient + }); + + it("should create permit when allowance is one unit below deposit amount", async () => { + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + balance: "500000", + assetAllowance: "999999", // One below deposit amount + assetPermitNonce: "0", + }); + + vi.mocked(useDeferredFacilitator).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + const result = await createPaymentExtraPayload(buyer, mockPaymentRequirements, [ + mockDepositConfig, + ]); + + expect(result).toBeDefined(); + expect(result?.permit).toBeDefined(); // Permit needed + }); +}); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts index 33a237f9f2..a6ecff2b55 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts @@ -3,7 +3,13 @@ import { Address, Chain, Log, Transport } from "viem"; import { createSigner, ConnectedClient, SignerWallet } from "../../../types/shared/evm"; import { PaymentRequirements, SchemeContext } from "../../../types/verify"; import { DeferredPaymentPayload, DEFERRRED_SCHEME } from "../../../types/verify/schemes/deferred"; -import { verify, settle, settleVoucher, depositWithAuthorization } from "./facilitator"; +import { + verify, + settle, + settleVoucher, + depositWithAuthorization, + getEscrowAccountDetails, +} from "./facilitator"; import { VoucherStore } from "./store"; import * as verifyModule from "./verify"; @@ -878,3 +884,307 @@ describe("facilitator - depositWithAuthorization", () => { expect(mockWallet.waitForTransactionReceipt).toHaveBeenCalledTimes(2); }); }); + +describe("facilitator - getEscrowAccountDetails", () => { + let mockClient: ConnectedClient; + let mockVoucherStore: VoucherStore; + + beforeEach(() => { + vi.clearAllMocks(); + + mockClient = { + chain: { id: 84532 }, + readContract: vi.fn(), + } as unknown as ConnectedClient; + + mockVoucherStore = { + getVouchers: vi.fn(), + } as unknown as VoucherStore; + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it("should return account details successfully with no outstanding vouchers", async () => { + vi.mocked(mockVoucherStore.getVouchers).mockResolvedValue([]); + vi.mocked(mockClient.readContract).mockResolvedValue([ + BigInt(5000000), // balance + BigInt(2000000), // allowance + BigInt(10), // nonce + ]); + + const result = await getEscrowAccountDetails( + mockClient, + buyerAddress as Address, + sellerAddress as Address, + assetAddress as Address, + escrowAddress as Address, + 84532, + mockVoucherStore, + ); + + expect(mockVoucherStore.getVouchers).toHaveBeenCalledWith( + { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + escrow: escrowAddress, + chainId: 84532, + latest: true, + }, + { + limit: 1_000, + }, + ); + + expect(mockClient.readContract).toHaveBeenCalledWith({ + address: escrowAddress, + abi: expect.any(Array), + functionName: "getAccountDetails", + args: [buyerAddress, sellerAddress, assetAddress, [], []], + }); + + expect(result).toEqual({ + balance: "5000000", + assetAllowance: "2000000", + assetPermitNonce: "10", + }); + }); + + it("should return account details successfully with outstanding vouchers", async () => { + const mockVouchers = [ + { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c", + }, + { + id: "0x8b4f0c21f9c7af0c5f96d32c8e6f4e79bc2c8e5735c6ef49c2gg9e581bc8g5g2", + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "500000", + asset: assetAddress, + timestamp: 1715769700, + nonce: 1, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769700 + 1000 * 60 * 60 * 24 * 30, + signature: + "0x79ce97f6d1242aa7b6f4826efb553ed453fd6c7132c665d95bc226d5f3027dd5456d61ed1bd8da5de6cea4d8154070ff458300b6b84e0c9010f434af77ad3d291c", + }, + ]; + + vi.mocked(mockVoucherStore.getVouchers).mockResolvedValue(mockVouchers); + vi.mocked(mockClient.readContract).mockResolvedValue([ + BigInt(3500000), // balance (adjusted for outstanding vouchers) + BigInt(2000000), // allowance + BigInt(5), // nonce + ]); + + const result = await getEscrowAccountDetails( + mockClient, + buyerAddress as Address, + sellerAddress as Address, + assetAddress as Address, + escrowAddress as Address, + 84532, + mockVoucherStore, + ); + + expect(mockClient.readContract).toHaveBeenCalledWith({ + address: escrowAddress, + abi: expect.any(Array), + functionName: "getAccountDetails", + args: [ + buyerAddress, + sellerAddress, + assetAddress, + [voucherId, "0x8b4f0c21f9c7af0c5f96d32c8e6f4e79bc2c8e5735c6ef49c2gg9e581bc8g5g2"], + [BigInt(1000000), BigInt(500000)], + ], + }); + + expect(result).toEqual({ + balance: "3500000", + assetAllowance: "2000000", + assetPermitNonce: "5", + }); + }); + + it("should return error when contract call fails", async () => { + vi.mocked(mockVoucherStore.getVouchers).mockResolvedValue([]); + vi.mocked(mockClient.readContract).mockRejectedValue(new Error("Contract call failed")); + + const result = await getEscrowAccountDetails( + mockClient, + buyerAddress as Address, + sellerAddress as Address, + assetAddress as Address, + escrowAddress as Address, + 84532, + mockVoucherStore, + ); + + expect(result).toEqual({ + error: "invalid_deferred_evm_contract_call_failed_account_details", + }); + }); + + it("should handle voucher store errors gracefully", async () => { + vi.mocked(mockVoucherStore.getVouchers).mockRejectedValue(new Error("Store error")); + + await expect( + getEscrowAccountDetails( + mockClient, + buyerAddress as Address, + sellerAddress as Address, + assetAddress as Address, + escrowAddress as Address, + 84532, + mockVoucherStore, + ), + ).rejects.toThrow("Store error"); + }); + + it("should handle large number of outstanding vouchers", async () => { + const manyVouchers = Array.from({ length: 100 }, (_, i) => ({ + id: `0x${i.toString(16).padStart(64, "0")}`, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "10000", + asset: assetAddress, + timestamp: 1715769600 + i, + nonce: i, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0x899b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c", + })); + + vi.mocked(mockVoucherStore.getVouchers).mockResolvedValue(manyVouchers); + vi.mocked(mockClient.readContract).mockResolvedValue([ + BigInt(4000000), // balance + BigInt(1000000), // allowance + BigInt(3), // nonce + ]); + + const result = await getEscrowAccountDetails( + mockClient, + buyerAddress as Address, + sellerAddress as Address, + assetAddress as Address, + escrowAddress as Address, + 84532, + mockVoucherStore, + ); + + expect(result).toEqual({ + balance: "4000000", + assetAllowance: "1000000", + assetPermitNonce: "3", + }); + + const contractCallArgs = vi.mocked(mockClient.readContract).mock.calls[0][0]; + expect(contractCallArgs.args?.[3]).toHaveLength(100); // All voucher IDs included + expect(contractCallArgs.args?.[4]).toHaveLength(100); // All voucher values included + }); + + it("should handle zero balance", async () => { + vi.mocked(mockVoucherStore.getVouchers).mockResolvedValue([]); + vi.mocked(mockClient.readContract).mockResolvedValue([ + BigInt(0), // zero balance + BigInt(0), // zero allowance + BigInt(0), // zero nonce + ]); + + const result = await getEscrowAccountDetails( + mockClient, + buyerAddress as Address, + sellerAddress as Address, + assetAddress as Address, + escrowAddress as Address, + 84532, + mockVoucherStore, + ); + + expect(result).toEqual({ + balance: "0", + assetAllowance: "0", + assetPermitNonce: "0", + }); + }); + + it("should handle very large balances", async () => { + vi.mocked(mockVoucherStore.getVouchers).mockResolvedValue([]); + vi.mocked(mockClient.readContract).mockResolvedValue([ + BigInt("1000000000000000000"), // 1 ETH in wei + BigInt("500000000000000000"), // 0.5 ETH in wei + BigInt(999), // large nonce + ]); + + const result = await getEscrowAccountDetails( + mockClient, + buyerAddress as Address, + sellerAddress as Address, + assetAddress as Address, + escrowAddress as Address, + 84532, + mockVoucherStore, + ); + + expect(result).toEqual({ + balance: "1000000000000000000", + assetAllowance: "500000000000000000", + assetPermitNonce: "999", + }); + }); + + it("should call voucher store with correct filters", async () => { + const differentBuyer = "0x9876543210987654321098765432109876543210"; + const differentSeller = "0x8765432109876543210987654321098765432109"; + const differentAsset = "0x7654321098765432109876543210987654321098"; + const differentEscrow = "0x6543210987654321098765432109876543210987"; + + vi.mocked(mockVoucherStore.getVouchers).mockResolvedValue([]); + vi.mocked(mockClient.readContract).mockResolvedValue([ + BigInt(1000000), + BigInt(500000), + BigInt(1), + ]); + + await getEscrowAccountDetails( + mockClient, + differentBuyer as Address, + differentSeller as Address, + differentAsset as Address, + differentEscrow as Address, + 1, + mockVoucherStore, + ); + + expect(mockVoucherStore.getVouchers).toHaveBeenCalledWith( + { + buyer: differentBuyer, + seller: differentSeller, + asset: differentAsset, + escrow: differentEscrow, + chainId: 1, + latest: true, + }, + { + limit: 1_000, + }, + ); + }); +}); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts index 9f83091974..3fb1e8c2d3 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts @@ -6,8 +6,8 @@ import { DEFERRRED_SCHEME, DeferredEscrowDepositAuthorization, } from "../../../types/verify/schemes/deferred"; -import { createPayment } from "./client"; -import { decodePayment } from "./utils/paymentUtils"; +import { createPayment, createPaymentExtraPayload } from "./client"; +import { decodePayment, encodePayment } from "./utils/paymentUtils"; import { settle, verify } from "./facilitator"; import { InMemoryVoucherStore } from "./store.mock"; import { getPaymentRequirementsExtra } from "./server"; @@ -15,6 +15,16 @@ import { Chain, Log, TransactionReceipt, Transport } from "viem"; import { signPermit, signDepositAuthorizationInner } from "./sign"; import { createPaymentHeader } from "../../../client"; +vi.mock("../../../verify/useDeferred", () => ({ + useDeferredFacilitator: vi.fn().mockReturnValue({ + getEscrowAccountDetails: vi.fn().mockResolvedValue({ + balance: "10000000", + assetAllowance: "1000000", + assetPermitNonce: "0", + }), + }), +})); + describe("Deferred Payment Integration Tests", () => { const sellerAddress = "0x1234567890123456789012345678901234567890"; const escrowAddress = "0xffffff12345678901234567890123456789fffff"; @@ -505,6 +515,336 @@ describe("Deferred Payment Integration Tests", () => { collectedAt: expect.any(Number), }); }); + + it("should handle complete payment lifecycle with createPaymentExtraPayload generating depositAuthorization", async () => { + // Initialize facilitator + const voucherStore = new InMemoryVoucherStore(); + const facilitatorWallet = { + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn(), + waitForTransactionReceipt: vi.fn(), + } as unknown as SignerWallet; + + // Create buyer + const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const buyerAddress = buyer.account.address; + + // * Step 1: Payment requirements generation with account details indicating low balance + const paymentRequirements = { + ...basePaymentRequirements, + extra: { + type: "new", + voucher: { + id: "0x9dce748efdc0ac6ce5875ae50b7cb8aff28d14e4f335b4f6393c2ed3866bc361", + escrow: escrowAddress, + }, + account: { + balance: "500", // Low balance - below threshold + assetAllowance: "0", // No allowance + assetPermitNonce: "0", + facilitator: "https://facilitator.x402.io", + }, + }, + } as DeferredPaymentRequirements; + + // Mock facilitator getEscrowAccountDetails call + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + balance: "500", // Confirm low balance + assetAllowance: "0", + assetPermitNonce: "0", + }); + (useDeferredFacilitator as ReturnType).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + }); + + // * Step 2: Client automatically generates deposit authorization using createPaymentExtraPayload + const depositConfig = { + asset: assetAddress, + assetDomain: { + name: "USD Coin", + version: "2", + }, + threshold: "10000", + amount: "1000000", + }; + + const extraPayload = await createPaymentExtraPayload(buyer, paymentRequirements, [ + depositConfig, + ]); + + expect(extraPayload).toBeDefined(); + expect(extraPayload?.permit).toBeDefined(); + expect(extraPayload?.depositAuthorization).toBeDefined(); + + // Verify facilitator was called to check balance + expect(mockGetEscrowAccountDetails).toHaveBeenCalledWith( + buyerAddress, + sellerAddress, + assetAddress, + escrowAddress, + 84532, + ); + + // * Step 3: Create payment with the deposit authorization + const paymentPayload = (await createPayment( + buyer, + 1, + paymentRequirements, + extraPayload, + )) as DeferredPaymentPayload; + + expect(paymentPayload.payload.depositAuthorization).toBeDefined(); + expect(paymentPayload.payload.depositAuthorization?.permit).toBeDefined(); + expect(paymentPayload.payload.depositAuthorization?.depositAuthorization).toBeDefined(); + + // * Step 4: Verify payment with deposit authorization (mock blockchain) + mockBlockchainInteractionsVerify(facilitatorWallet); + const verifyResponse = await verify(facilitatorWallet, paymentPayload, paymentRequirements, { + deferred: { voucherStore }, + }); + expect(verifyResponse.isValid).toBe(true); + + // * Step 5: Store voucher + voucherStore.storeVoucher({ + ...paymentPayload.payload.voucher, + signature: paymentPayload.payload.signature, + }); + + // * Step 6: Settle with deposit authorization (mock blockchain) + mockBlockchainInteractionsSettleWithDepositAuth(facilitatorWallet); + const settleResponse = await settle(facilitatorWallet, paymentPayload, paymentRequirements, { + deferred: { voucherStore }, + }); + expect(settleResponse.success).toBe(true); + + // Verify writeContract was called for permit, depositWithAuthorization, and collect + expect(facilitatorWallet.writeContract).toHaveBeenCalledTimes(3); + + // First call should be permit + const permitCall = vi.mocked(facilitatorWallet.writeContract).mock.calls[0][0]; + expect(permitCall).toMatchObject({ + functionName: "permit", + address: assetAddress, + }); + + // Second call should be depositWithAuthorization + const depositCall = vi.mocked(facilitatorWallet.writeContract).mock.calls[1][0]; + expect(depositCall.functionName).toBe("depositWithAuthorization"); + expect(depositCall.address.toLowerCase()).toBe(escrowAddress.toLowerCase()); + + // Third call should be collect + const collectCall = vi.mocked(facilitatorWallet.writeContract).mock.calls[2][0]; + expect(collectCall.functionName).toBe("collect"); + expect(collectCall.address.toLowerCase()).toBe(escrowAddress.toLowerCase()); + + // * Step 7: Verify voucher collection + const voucherCollections = await voucherStore.getVoucherCollections( + { + id: paymentPayload.payload.voucher.id, + nonce: paymentPayload.payload.voucher.nonce, + }, + {}, + ); + expect(voucherCollections.length).toBe(1); + expect(voucherCollections[0]).toEqual({ + voucherId: paymentPayload.payload.voucher.id, + voucherNonce: paymentPayload.payload.voucher.nonce, + chainId: paymentPayload.payload.voucher.chainId, + transactionHash: settleResponse.transaction, + collectedAmount: paymentPayload.payload.voucher.valueAggregate, + asset: paymentPayload.payload.voucher.asset, + collectedAt: expect.any(Number), + }); + }); + + it("should handle payment lifecycle without depositAuthorization when balance is sufficient", async () => { + // Initialize facilitator + const voucherStore = new InMemoryVoucherStore(); + const facilitatorWallet = { + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn(), + waitForTransactionReceipt: vi.fn(), + } as unknown as SignerWallet; + + // Create buyer + const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + + // * Step 1: Payment requirements generation with account details indicating sufficient balance + const paymentRequirements = { + ...basePaymentRequirements, + extra: { + type: "new", + voucher: { + id: "0x9dce748efdc0ac6ce5875ae50b7cb8aff28d14e4f335b4f6393c2ed3866bc361", + escrow: escrowAddress, + }, + account: { + balance: "10000000", // High balance - above threshold + assetAllowance: "1000000", + assetPermitNonce: "0", + facilitator: "https://facilitator.x402.io", + }, + }, + } as DeferredPaymentRequirements; + + // * Step 2: Client checks balance and decides no deposit needed + const depositConfig = { + asset: assetAddress, + assetDomain: { + name: "USD Coin", + version: "2", + }, + threshold: "10000", + amount: "1000000", + }; + + const extraPayload = await createPaymentExtraPayload(buyer, paymentRequirements, [ + depositConfig, + ]); + + // Should return undefined when balance is sufficient + expect(extraPayload).toBeUndefined(); + + // * Step 3: Create payment without deposit authorization + const paymentPayload = (await createPayment( + buyer, + 1, + paymentRequirements, + )) as DeferredPaymentPayload; + + expect(paymentPayload.payload.depositAuthorization).toBeUndefined(); + + // * Step 4: Verify and settle normally (mock blockchain) + mockBlockchainInteractionsVerify(facilitatorWallet); + const verifyResponse = await verify(facilitatorWallet, paymentPayload, paymentRequirements, { + deferred: { voucherStore }, + }); + expect(verifyResponse.isValid).toBe(true); + + voucherStore.storeVoucher({ + ...paymentPayload.payload.voucher, + signature: paymentPayload.payload.signature, + }); + + mockBlockchainInteractionsSettle(facilitatorWallet); + const settleResponse = await settle(facilitatorWallet, paymentPayload, paymentRequirements, { + deferred: { voucherStore }, + }); + expect(settleResponse.success).toBe(true); + + // Should only call writeContract once (for voucher collection, not for deposit) + expect(facilitatorWallet.writeContract).toHaveBeenCalledTimes(1); + }); + + it("should handle payment lifecycle with depositAuthorization but no permit when allowance is sufficient", async () => { + // Initialize facilitator + const voucherStore = new InMemoryVoucherStore(); + const facilitatorWallet = { + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn(), + waitForTransactionReceipt: vi.fn(), + } as unknown as SignerWallet; + + // Create buyer + const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const buyerAddress = buyer.account.address; + + // * Step 1: Payment requirements with low balance but sufficient allowance + const paymentRequirements = { + ...basePaymentRequirements, + extra: { + type: "new", + voucher: { + id: "0x9dce748efdc0ac6ce5875ae50b7cb8aff28d14e4f335b4f6393c2ed3866bc361", + escrow: escrowAddress, + }, + account: { + balance: "500", // Low balance + assetAllowance: "2000000", // Sufficient allowance - no permit needed + assetPermitNonce: "0", + facilitator: "https://facilitator.x402.io", + }, + }, + } as DeferredPaymentRequirements; + + // Mock facilitator call + const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); + const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + balance: "500", + assetAllowance: "2000000", + assetPermitNonce: "0", + }); + (useDeferredFacilitator as ReturnType).mockReturnValue({ + getEscrowAccountDetails: mockGetEscrowAccountDetails, + }); + + // * Step 2: Generate deposit authorization without permit + const depositConfig = { + asset: assetAddress, + assetDomain: { + name: "USD Coin", + version: "2", + }, + threshold: "10000", + amount: "1000000", + }; + + const extraPayload = await createPaymentExtraPayload(buyer, paymentRequirements, [ + depositConfig, + ]); + + expect(extraPayload).toBeDefined(); + expect(extraPayload?.permit).toBeUndefined(); // No permit needed + expect(extraPayload?.depositAuthorization).toBeDefined(); + + // * Step 3: Create and verify payment + const paymentPayload = (await createPayment( + buyer, + 1, + paymentRequirements, + extraPayload, + )) as DeferredPaymentPayload; + + mockBlockchainInteractionsVerify(facilitatorWallet); + const verifyResponse = await verify(facilitatorWallet, paymentPayload, paymentRequirements, { + deferred: { voucherStore }, + }); + expect(verifyResponse.isValid).toBe(true); + + voucherStore.storeVoucher({ + ...paymentPayload.payload.voucher, + signature: paymentPayload.payload.signature, + }); + + // * Step 4: Settle without permit transaction + mockBlockchainInteractionsSettleWithDepositAuthNoPermit(facilitatorWallet); + const settleResponse = await settle(facilitatorWallet, paymentPayload, paymentRequirements, { + deferred: { voucherStore }, + }); + expect(settleResponse.success).toBe(true); + + // Should call writeContract twice (depositWithAuthorization + collect, no permit) + expect(facilitatorWallet.writeContract).toHaveBeenCalledTimes(2); + const depositCall = vi.mocked(facilitatorWallet.writeContract).mock.calls[0][0]; + expect(depositCall.functionName).toBe("depositWithAuthorization"); + expect(depositCall.address.toLowerCase()).toBe(escrowAddress.toLowerCase()); + const collectCall = vi.mocked(facilitatorWallet.writeContract).mock.calls[1][0]; + expect(collectCall.functionName).toBe("collect"); + expect(collectCall.address.toLowerCase()).toBe(escrowAddress.toLowerCase()); + }); }); describe("Multi-round voucher aggregation", () => { @@ -621,6 +961,36 @@ function mockBlockchainInteractionsSettle(wallet: SignerWallet * @param wallet - The wallet to mock blockchain interactions for */ function mockBlockchainInteractionsVerify(wallet: SignerWallet) { + vi.mocked(wallet.readContract).mockImplementation(async (args: { functionName: string }) => { + if (args.functionName === "getOutstandingAndCollectableAmount") { + return [BigInt(1_000_000)]; + } + if (args.functionName === "getAccount") { + return { + balance: BigInt(10_000_000), + thawingAmount: BigInt(0), + thawEndTime: BigInt(0), + }; + } + if (args.functionName === "nonces") { + return BigInt(0); + } + if (args.functionName === "isDepositAuthorizationNonceUsed") { + return false; + } + if (args.functionName === "allowance") { + return BigInt(10_000_000); // Sufficient allowance for deposits without permit + } + throw new Error(`Unmocked contract read: ${args.functionName}`); + }); +} + +/** + * Mock blockchain interactions for settle with deposit authorization (with permit) + * + * @param wallet - The wallet to mock blockchain interactions for + */ +function mockBlockchainInteractionsSettleWithDepositAuth(wallet: SignerWallet) { vi.mocked(wallet.readContract).mockImplementation(async (args: { functionName: string }) => { if (args.functionName === "getOutstandingAndCollectableAmount") { return [BigInt(1_000_000)]; @@ -640,4 +1010,66 @@ function mockBlockchainInteractionsVerify(wallet: SignerWallet } throw new Error(`Unmocked contract read: ${args.functionName}`); }); + vi.mocked(wallet.writeContract).mockResolvedValue("0x1234567890abcdef"); + vi.mocked(wallet.waitForTransactionReceipt).mockResolvedValue({ + status: "success", + logs: [ + { + data: "0x000000000000000000000000111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000003f900000000000000000000000000000000000000000000000000000000000003f9", + topics: [ + "0x9cc196634f792f4e61cf0cd71e2fbbd459e54c5e57a9bad3e6f7b6e79503cc70", + "0x198e73e1cecf59db4fbf8ca10000000000000000000000000000000000000000", + "0x00000000000000000000000080cdf1957ebb7a2df22dd8913753a4423ff4272e", + "0x000000000000000000000000c93d37ad45c907ee1b27a02b2e1bd823ba9d379c", + ], + } as unknown as Log, + ], + } as TransactionReceipt); +} + +/** + * Mock blockchain interactions for settle with deposit authorization (no permit) + * + * @param wallet - The wallet to mock blockchain interactions for + */ +function mockBlockchainInteractionsSettleWithDepositAuthNoPermit( + wallet: SignerWallet, +) { + vi.mocked(wallet.readContract).mockImplementation(async (args: { functionName: string }) => { + if (args.functionName === "getOutstandingAndCollectableAmount") { + return [BigInt(1_000_000)]; + } + if (args.functionName === "getAccount") { + return { + balance: BigInt(10_000_000), + thawingAmount: BigInt(0), + thawEndTime: BigInt(0), + }; + } + if (args.functionName === "nonces") { + return BigInt(0); + } + if (args.functionName === "isDepositAuthorizationNonceUsed") { + return false; + } + if (args.functionName === "allowance") { + return BigInt(10_000_000); // Sufficient allowance for deposits without permit + } + throw new Error(`Unmocked contract read: ${args.functionName}`); + }); + vi.mocked(wallet.writeContract).mockResolvedValue("0x1234567890abcdef"); + vi.mocked(wallet.waitForTransactionReceipt).mockResolvedValue({ + status: "success", + logs: [ + { + data: "0x000000000000000000000000111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000003f900000000000000000000000000000000000000000000000000000000000003f9", + topics: [ + "0x9cc196634f792f4e61cf0cd71e2fbbd459e54c5e57a9bad3e6f7b6e79503cc70", + "0x198e73e1cecf59db4fbf8ca10000000000000000000000000000000000000000", + "0x00000000000000000000000080cdf1957ebb7a2df22dd8913753a4423ff4272e", + "0x000000000000000000000000c93d37ad45c907ee1b27a02b2e1bd823ba9d379c", + ], + } as unknown as Log, + ], + } as TransactionReceipt); } diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index 1e2c5e02bd..d969ab99ed 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -71,7 +71,7 @@ export function verifyPaymentRequirements( paymentRequirements.extra.type === "new" ? BigInt(paymentRequirements.maxAmountRequired) : BigInt(paymentRequirements.maxAmountRequired) + - BigInt(paymentRequirements.extra.voucher.valueAggregate); + BigInt(paymentRequirements.extra.voucher.valueAggregate); if (BigInt(paymentPayload.payload.voucher.valueAggregate) < requiredVoucherValueAggregate) { return { isValid: false, From 685816ca1ddca29f33b49db7054e4223e4ca545c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 14 Oct 2025 16:17:52 -0300 Subject: [PATCH 097/116] chore: lint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../packages/x402/src/schemes/deferred/evm/integration.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts index 3fb1e8c2d3..69ac94431f 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts @@ -7,7 +7,7 @@ import { DeferredEscrowDepositAuthorization, } from "../../../types/verify/schemes/deferred"; import { createPayment, createPaymentExtraPayload } from "./client"; -import { decodePayment, encodePayment } from "./utils/paymentUtils"; +import { decodePayment } from "./utils/paymentUtils"; import { settle, verify } from "./facilitator"; import { InMemoryVoucherStore } from "./store.mock"; import { getPaymentRequirementsExtra } from "./server"; @@ -760,7 +760,6 @@ describe("Deferred Payment Integration Tests", () => { "base-sepolia", "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", ); - const buyerAddress = buyer.account.address; // * Step 1: Payment requirements with low balance but sufficient allowance const paymentRequirements = { From dbad6d18966dc8b3f76c95f53e2f8ae40dd7e43e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 14 Oct 2025 16:35:09 -0300 Subject: [PATCH 098/116] chore: remove python deferred lib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- python/TODO.md | 75 ------- python/deferred_implementation_plan.md | 105 --------- python/x402/README.md | 37 --- python/x402/src/x402/clients/base.py | 61 +++-- python/x402/src/x402/clients/httpx.py | 4 +- python/x402/src/x402/clients/requests.py | 4 - python/x402/src/x402/deferred.py | 260 ---------------------- python/x402/src/x402/exact.py | 2 +- python/x402/src/x402/types.py | 72 +----- python/x402/tests/test_deferred.py | 272 ----------------------- 10 files changed, 30 insertions(+), 862 deletions(-) delete mode 100644 python/TODO.md delete mode 100644 python/deferred_implementation_plan.md delete mode 100644 python/x402/src/x402/deferred.py delete mode 100644 python/x402/tests/test_deferred.py diff --git a/python/TODO.md b/python/TODO.md deleted file mode 100644 index 0e23e32aa0..0000000000 --- a/python/TODO.md +++ /dev/null @@ -1,75 +0,0 @@ -# Python Deferred Payment Scheme - TODO - -## What we built - -✅ **Completed:** -- Added new type definitions for deferred payments: - - `DeferredEvmPayloadVoucher` - Full voucher structure with all fields - - `DeferredPaymentPayload` - Payload containing signature and voucher - - `DeferredPaymentRequirementsExtra*` - Discriminated unions for new/aggregation - - Updated `SchemePayloads` union to include deferred - -- Created `deferred.py` module with: - - `prepare_payment_header()` - Creates unsigned deferred payments - - `create_new_voucher()` - Creates new vouchers with initial valueAggregate - - `aggregate_voucher()` - Aggregates existing vouchers (increments valueAggregate) - - `sign_voucher()` - EIP-712 signing for DeferredPaymentEscrow domain - - `verify_voucher()` - Verifies voucher signatures - - Full encode/decode support - -- Updated client integration: - - Modified `base.py` to support both exact and deferred schemes - - Added scheme detection and routing in `create_payment_header()` - - Updated payment requirements selector to accept deferred - -- Wrote comprehensive unit tests (test_deferred.py): - - New voucher creation - - Voucher signing and verification - - Voucher aggregation with validation - - Expired voucher handling - - Encoding/decoding - -## Things to fix eventually - -### High Priority -- [x] Test runner setup - Tests are now passing with uv -- [x] Fixed nonce encoding bug in exact.py (was returning bytes instead of hex) -- [ ] Integration tests with actual HTTP clients (httpx/requests) -- [ ] Verify EIP-712 signature format matches TypeScript exactly -- [ ] Add proper error handling for network errors during aggregation - -### Medium Priority -- [ ] Add support for smart account signature verification (noted in TypeScript TODO) -- [ ] Implement batch voucher collection support (collectMany) -- [ ] Add voucher storage/retrieval helpers for managing multiple vouchers -- [ ] Performance optimization for voucher lookups - -### Low Priority -- [ ] Add comprehensive logging for debugging -- [ ] Create example scripts showing deferred payment flows -- [ ] Document differences between exact and deferred schemes -- [ ] Add type hints for all function parameters - -## Security Notes - -⚠️ **Important security considerations:** -- Voucher signatures MUST be verified before aggregation -- Expiry timestamps need to be checked to prevent expired voucher usage -- Chain ID validation is critical to prevent cross-chain replay attacks -- Value aggregation must be monotonically increasing -- Currently assumes trusted input for voucher data - needs validation in production - -## Testing Notes - -The test suite covers the core functionality but hasn't been run yet due to environment setup. Before using in production: -1. Run full test suite -2. Add integration tests with real escrow contracts -3. Test edge cases around timestamp boundaries -4. Verify signature compatibility with TypeScript implementation - -## Implementation Notes - -- Used eth_account for EIP-712 signing (same as exact scheme) -- Followed TypeScript structure closely for compatibility -- 30-day default expiry matches TypeScript -- Checksum addresses used throughout for consistency \ No newline at end of file diff --git a/python/deferred_implementation_plan.md b/python/deferred_implementation_plan.md deleted file mode 100644 index e1b57bf3ec..0000000000 --- a/python/deferred_implementation_plan.md +++ /dev/null @@ -1,105 +0,0 @@ -# Python Deferred Payment Scheme Implementation Plan - -## Overview -This document outlines the implementation plan for adding deferred payment scheme support to the Python x402 client, based on the existing TypeScript implementation. - -## Implementation Steps - -### 1. Add Type Definitions (types.py) - -Add the following new types to support deferred payments: - -```python -class DeferredEvmPayloadVoucher(BaseModel): - id: str # Hex encoded 64 bytes (bytes32) - buyer: str # EVM address - seller: str # EVM address - value_aggregate: str # Total outstanding amount, monotonically increasing - asset: str # ERC-20 token address - timestamp: int # Unix timestamp - nonce: int # Incremented with each aggregation - escrow: str # Escrow contract address - chain_id: int # Network chain ID - expiry: int # Expiration timestamp - -class DeferredPaymentPayload(BaseModel): - signature: str - voucher: DeferredEvmPayloadVoucher - -class DeferredPaymentRequirementsExtraNewVoucher(BaseModel): - type: Literal["new"] - voucher: dict # Contains only 'id' and 'escrow' fields - -class DeferredPaymentRequirementsExtraAggregationVoucher(BaseModel): - type: Literal["aggregation"] - signature: str - voucher: DeferredEvmPayloadVoucher - -# Update SchemePayloads union -SchemePayloads = Union[ExactPaymentPayload, DeferredPaymentPayload] -``` - -### 2. Create Deferred Module (deferred.py) - -Implement core deferred payment functionality: - -```python -# Constants -EXPIRY_TIME = 60 * 60 * 24 * 30 # 30 days -DEFERRED_SCHEME = "deferred" - -# Core functions -def prepare_payment_header(sender_address, x402_version, payment_requirements) -def create_new_voucher(buyer, payment_requirements) -def aggregate_voucher(buyer, payment_requirements) -def sign_voucher(account, voucher) -def verify_voucher(voucher, signature, signer) -def sign_payment_header(account, payment_requirements, header) -def encode_payment(payment_payload) -``` - -### 3. EIP-712 Typed Data Structure - -The deferred scheme uses different typed data: -- Domain: "DeferredPaymentEscrow" (vs "EIP712Domain" for exact) -- Primary type: Custom voucher structure (vs "TransferWithAuthorization") -- Message fields: id, buyer, seller, valueAggregate, asset, timestamp, nonce, escrow, chainId, expiry - -### 4. Update Client Integration - -Modify client code to: -- Detect scheme type from payment requirements -- Route to appropriate payment header creation function -- Handle both new voucher creation and aggregation flows - -### 5. Testing Requirements - -- Unit tests for voucher creation and aggregation -- EIP-712 signature verification tests -- Integration tests with httpx/requests clients -- Edge cases: expired vouchers, invalid signatures, timestamp validation - -## Key Differences from Exact Scheme - -1. **Voucher-based**: Uses signed vouchers instead of EIP-3009 authorizations -2. **Aggregation**: Supports increasing payment amounts over time -3. **Escrow model**: Funds are pre-deposited in escrow contract -4. **Expiry handling**: Vouchers have expiration timestamps -5. **Nonce management**: Increments with each aggregation (not random) - -## TODO Items for MVP - -- [ ] Implement basic voucher creation and signing -- [ ] Add voucher aggregation logic -- [ ] Integrate with existing client classes -- [ ] Add comprehensive error handling -- [ ] Write unit tests for core functionality -- [ ] Add integration tests -- [ ] Update documentation - -## Future Enhancements - -- Smart account support for signature verification -- Batch voucher collection support -- Advanced expiry management -- Performance optimizations for voucher storage/retrieval \ No newline at end of file diff --git a/python/x402/README.md b/python/x402/README.md index 9c790d9553..f6441e9f2f 100644 --- a/python/x402/README.md +++ b/python/x402/README.md @@ -80,43 +80,6 @@ payment_middleware.add( ) ``` -## Payment Schemes - -The x402 protocol supports multiple payment schemes. Currently supported: - -- **`exact`**: Traditional EIP-3009 payments with immediate settlement -- **`deferred`**: Voucher-based payments with aggregation and batch settlement - -### Deferred Payment Scheme - -The deferred scheme enables efficient micropayments by allowing sellers to accumulate signed vouchers and redeem them in batches: - -```py -# The client automatically handles both exact and deferred schemes -# based on the server's payment requirements - -from eth_account import Account -from x402.clients.httpx import x402HttpxClient - -account = Account.from_key("your_private_key") - -async with x402HttpxClient(account=account, base_url="https://api.example.com") as client: - # First request creates a new voucher - response1 = await client.get("/api/endpoint") - - # Subsequent requests aggregate to the same voucher - response2 = await client.get("/api/endpoint") - - # The valueAggregate increases with each request - # Seller can batch redeem vouchers later -``` - -Key features of deferred payments: -- Vouchers are aggregated offchain, reducing gas costs -- Value accumulates monotonically (always increases) -- 30-day default expiry for vouchers -- Sellers batch redeem when it's economically efficient - ## Client Integration ### Simple Usage diff --git a/python/x402/src/x402/clients/base.py b/python/x402/src/x402/clients/base.py index 7d18392153..e2e8c1023e 100644 --- a/python/x402/src/x402/clients/base.py +++ b/python/x402/src/x402/clients/base.py @@ -1,9 +1,7 @@ +import time from typing import Optional, Callable, Dict, Any, List from eth_account import Account -from x402.exact import sign_payment_header as sign_exact_payment_header -from x402.exact import prepare_payment_header as prepare_exact_payment_header -from x402.deferred import sign_payment_header as sign_deferred_payment_header -from x402.deferred import prepare_payment_header as prepare_deferred_payment_header +from x402.exact import sign_payment_header from x402.types import ( PaymentRequirements, UnsupportedSchemeException, @@ -118,7 +116,7 @@ def default_payment_requirements_selector( if network_filter and network != network_filter: continue - if scheme in ["exact", "deferred"]: + if scheme == "exact": # Check max value if set if max_value is not None: max_amount = int(paymentRequirements.max_amount_required) @@ -169,35 +167,30 @@ def create_payment_header( Returns: Signed payment header """ - scheme = payment_requirements.scheme - - if scheme == "exact": - # Create exact payment header - unsigned_header = prepare_exact_payment_header( - self.account.address, - x402_version, - payment_requirements - ) - signed_header = sign_exact_payment_header( - self.account, - payment_requirements, - unsigned_header, - ) - elif scheme == "deferred": - # Create deferred payment header - unsigned_header = prepare_deferred_payment_header( - self.account.address, - x402_version, - payment_requirements - ) - signed_header = sign_deferred_payment_header( - self.account, - payment_requirements, - unsigned_header, - ) - else: - raise UnsupportedSchemeException(f"Unsupported payment scheme: {scheme}") - + unsigned_header = { + "x402Version": x402_version, + "scheme": payment_requirements.scheme, + "network": payment_requirements.network, + "payload": { + "signature": None, + "authorization": { + "from": self.account.address, + "to": payment_requirements.pay_to, + "value": payment_requirements.max_amount_required, + "validAfter": str(int(time.time()) - 60), # 60 seconds before + "validBefore": str( + int(time.time()) + payment_requirements.max_timeout_seconds + ), + "nonce": self.generate_nonce(), + }, + }, + } + + signed_header = sign_payment_header( + self.account, + payment_requirements, + unsigned_header, + ) return signed_header def generate_nonce(self): diff --git a/python/x402/src/x402/clients/httpx.py b/python/x402/src/x402/clients/httpx.py index 8b49e259df..430cfb8ee4 100644 --- a/python/x402/src/x402/clients/httpx.py +++ b/python/x402/src/x402/clients/httpx.py @@ -17,9 +17,7 @@ def __init__(self, client: x402Client): async def on_request(self, request: Request): """Handle request before it is sent.""" - # Add buyer header to identify the account - if self.client.account and hasattr(self.client.account, 'address'): - request.headers["X-PAYMENT-BUYER"] = self.client.account.address + pass async def on_response(self, response: Response) -> Response: """Handle response after it is received.""" diff --git a/python/x402/src/x402/clients/requests.py b/python/x402/src/x402/clients/requests.py index 27e99de437..fee5346944 100644 --- a/python/x402/src/x402/clients/requests.py +++ b/python/x402/src/x402/clients/requests.py @@ -36,10 +36,6 @@ def send(self, request, **kwargs): Returns: Response object """ - # Add buyer header to identify the account - if not self._is_retry and self.client.account and hasattr(self.client.account, 'address'): - request.headers["X-PAYMENT-BUYER"] = self.client.account.address - if self._is_retry: self._is_retry = False return super().send(request, **kwargs) diff --git a/python/x402/src/x402/deferred.py b/python/x402/src/x402/deferred.py deleted file mode 100644 index af84cba01e..0000000000 --- a/python/x402/src/x402/deferred.py +++ /dev/null @@ -1,260 +0,0 @@ -import time -import json -from typing import Dict, Any -from typing_extensions import TypedDict - -from eth_account import Account -from eth_account.messages import encode_typed_data -from eth_utils import to_checksum_address -from hexbytes import HexBytes - -from x402.encoding import safe_base64_encode, safe_base64_decode -from x402.types import ( - PaymentRequirements, - DeferredEvmPayloadVoucher, - DeferredPaymentPayload, - DeferredPaymentRequirementsExtraNewVoucher, - DeferredPaymentRequirementsExtraAggregationVoucher, -) -from x402.chains import get_chain_id - -# Constants -EXPIRY_TIME = 60 * 60 * 24 * 30 # 30 days -DEFERRED_SCHEME = "deferred" - - -class PaymentHeader(TypedDict): - x402Version: int - scheme: str - network: str - payload: dict[str, Any] - - -def prepare_payment_header( - sender_address: str, x402_version: int, payment_requirements: PaymentRequirements -) -> Dict[str, Any]: - """Prepare an unsigned deferred payment header.""" - # Check if extra is a dict and has 'type' field - if not payment_requirements.extra or "type" not in payment_requirements.extra: - raise ValueError("Payment requirements extra must contain 'type' field") - - extra_type = payment_requirements.extra["type"] - - if extra_type == "new": - voucher = create_new_voucher(sender_address, payment_requirements) - elif extra_type == "aggregation": - voucher = aggregate_voucher(sender_address, payment_requirements) - else: - raise ValueError(f"Unknown voucher type: {extra_type}") - - return { - "x402Version": x402_version, - "scheme": DEFERRED_SCHEME, - "network": payment_requirements.network, - "payload": { - "signature": None, - "voucher": voucher.model_dump(by_alias=True), - }, - } - - -def create_new_voucher( - buyer: str, payment_requirements: PaymentRequirements -) -> DeferredEvmPayloadVoucher: - """Create a new voucher with the given payment requirements.""" - # Validate extra data structure - try: - extra = DeferredPaymentRequirementsExtraNewVoucher(**payment_requirements.extra) - except Exception as e: - raise ValueError(f"Invalid extra data for new voucher: {e}") - - return DeferredEvmPayloadVoucher( - id=extra.voucher["id"], - buyer=to_checksum_address(buyer), - seller=to_checksum_address(payment_requirements.pay_to), - value_aggregate=payment_requirements.max_amount_required, - asset=to_checksum_address(payment_requirements.asset), - timestamp=int(time.time()), - nonce=0, - escrow=to_checksum_address(extra.voucher["escrow"]), - chain_id=int(get_chain_id(payment_requirements.network)), - expiry=int(time.time()) + EXPIRY_TIME, - ) - - -def aggregate_voucher( - buyer: str, payment_requirements: PaymentRequirements -) -> DeferredEvmPayloadVoucher: - """Aggregate a voucher with new payment requirements.""" - # Validate extra data structure - try: - extra = DeferredPaymentRequirementsExtraAggregationVoucher(**payment_requirements.extra) - except Exception as e: - raise ValueError(f"Invalid extra data for voucher aggregation: {e}") - - voucher = extra.voucher - now = int(time.time()) - - # Verify previous voucher matches payment requirements - if payment_requirements.pay_to.lower() != voucher.seller.lower(): - raise ValueError("Invalid voucher seller") - if payment_requirements.asset.lower() != voucher.asset.lower(): - raise ValueError("Invalid voucher asset") - if int(get_chain_id(payment_requirements.network)) != voucher.chain_id: - raise ValueError("Invalid voucher chainId") - if now > voucher.expiry: - raise ValueError("Voucher expired") - if now < voucher.timestamp: - raise ValueError("Voucher timestamp is in the future") - - # Verify signature is valid and the voucher's buyer is the client - is_valid = verify_voucher(voucher, extra.signature, buyer) - if not is_valid: - raise ValueError("Invalid voucher signature") - - # Create aggregated voucher - new_value_aggregate = str( - int(payment_requirements.max_amount_required) + int(voucher.value_aggregate) - ) - - return DeferredEvmPayloadVoucher( - id=voucher.id, - buyer=to_checksum_address(buyer), - seller=voucher.seller, - value_aggregate=new_value_aggregate, - asset=voucher.asset, - timestamp=now, - nonce=voucher.nonce + 1, - escrow=voucher.escrow, - chain_id=voucher.chain_id, - expiry=now + EXPIRY_TIME, - ) - - -def get_voucher_typed_data(voucher: DeferredEvmPayloadVoucher) -> Dict[str, Any]: - """Get the EIP-712 typed data for a voucher.""" - return { - "types": { - "EIP712Domain": [ - {"name": "name", "type": "string"}, - {"name": "version", "type": "string"}, - {"name": "chainId", "type": "uint256"}, - {"name": "verifyingContract", "type": "address"}, - ], - "Voucher": [ - {"name": "id", "type": "bytes32"}, - {"name": "buyer", "type": "address"}, - {"name": "seller", "type": "address"}, - {"name": "valueAggregate", "type": "uint256"}, - {"name": "asset", "type": "address"}, - {"name": "timestamp", "type": "uint64"}, - {"name": "nonce", "type": "uint256"}, - {"name": "escrow", "type": "address"}, - {"name": "chainId", "type": "uint256"}, - {"name": "expiry", "type": "uint64"}, - ] - }, - "primaryType": "Voucher", - "domain": { - "name": "DeferredPaymentEscrow", - "version": "1", - "chainId": voucher.chain_id, - "verifyingContract": to_checksum_address(voucher.escrow), - }, - "message": { - "id": voucher.id, - "buyer": to_checksum_address(voucher.buyer), - "seller": to_checksum_address(voucher.seller), - "valueAggregate": int(voucher.value_aggregate), - "asset": to_checksum_address(voucher.asset), - "timestamp": voucher.timestamp, - "nonce": voucher.nonce, - "escrow": to_checksum_address(voucher.escrow), - "chainId": voucher.chain_id, - "expiry": voucher.expiry, - }, - } - - -def sign_voucher(account: Account, voucher: DeferredEvmPayloadVoucher) -> str: - """Sign a voucher using EIP-712.""" - typed_data = get_voucher_typed_data(voucher) - - # Encode the typed data - signable_message = encode_typed_data( - domain_data=typed_data["domain"], - message_types={k: v for k, v in typed_data["types"].items() if k != "EIP712Domain"}, - message_data=typed_data["message"], - ) - - # Sign the message - signed_message = account.sign_message(signable_message) - signature = signed_message.signature.hex() - - if not signature.startswith("0x"): - signature = f"0x{signature}" - - return signature - - -def verify_voucher( - voucher: DeferredEvmPayloadVoucher, signature: str, signer: str -) -> bool: - """Verify a voucher signature.""" - typed_data = get_voucher_typed_data(voucher) - - # Encode the typed data - signable_message = encode_typed_data( - domain_data=typed_data["domain"], - message_types={k: v for k, v in typed_data["types"].items() if k != "EIP712Domain"}, - message_data=typed_data["message"], - ) - - # Recover the signer address - recovered_address = Account.recover_message(signable_message, signature=signature) - - return recovered_address.lower() == signer.lower() - - -def sign_payment_header( - account: Account, payment_requirements: PaymentRequirements, header: PaymentHeader -) -> str: - """Sign a deferred payment header using the account's private key.""" - try: - voucher_dict = header["payload"]["voucher"] - voucher = DeferredEvmPayloadVoucher(**voucher_dict) - - # Sign the voucher - signature = sign_voucher(account, voucher) - - # Update the header with the signature - header["payload"]["signature"] = signature - - # Encode the payment - encoded = encode_payment(header) - return encoded - except Exception as e: - raise Exception(f"Failed to sign payment header: {e}") - - -def encode_payment(payment_payload: Dict[str, Any]) -> str: - """Encode a payment payload into a base64 string.""" - from hexbytes import HexBytes - - def default(obj): - if isinstance(obj, HexBytes): - return obj.hex() - if hasattr(obj, "to_dict"): - return obj.to_dict() - if hasattr(obj, "hex"): - return obj.hex() - raise TypeError( - f"Object of type {obj.__class__.__name__} is not JSON serializable" - ) - - return safe_base64_encode(json.dumps(payment_payload, default=default)) - - -def decode_payment(encoded_payment: str) -> Dict[str, Any]: - """Decode a base64 encoded payment string.""" - return json.loads(safe_base64_decode(encoded_payment)) \ No newline at end of file diff --git a/python/x402/src/x402/exact.py b/python/x402/src/x402/exact.py index 528df927c9..4972b4612b 100644 --- a/python/x402/src/x402/exact.py +++ b/python/x402/src/x402/exact.py @@ -38,7 +38,7 @@ def prepare_payment_header( "value": payment_requirements.max_amount_required, "validAfter": valid_after, "validBefore": valid_before, - "nonce": nonce.hex(), + "nonce": nonce, }, }, } diff --git a/python/x402/src/x402/types.py b/python/x402/src/x402/types.py index 7e95a3ff48..236417affd 100644 --- a/python/x402/src/x402/types.py +++ b/python/x402/src/x402/types.py @@ -190,78 +190,8 @@ class SettleResponse(BaseModel): ) -# Deferred payment types -class DeferredEvmPayloadVoucher(BaseModel): - """Represents a deferred payment voucher for EVM chains""" - - id: str # Hex encoded 64 bytes (bytes32) - buyer: str # EVM address - seller: str # EVM address - value_aggregate: str # Total outstanding amount, monotonically increasing - asset: str # ERC-20 token address - timestamp: int # Unix timestamp - nonce: int # Incremented with each aggregation - escrow: str # Escrow contract address - chain_id: int # Network chain ID - expiry: int # Expiration timestamp - - model_config = ConfigDict( - alias_generator=to_camel, - populate_by_name=True, - from_attributes=True, - ) - - @field_validator("value_aggregate") - def validate_value_aggregate(cls, v): - try: - int(v) - except ValueError: - raise ValueError("value_aggregate must be an integer encoded as a string") - return v - - -class DeferredPaymentPayload(BaseModel): - """Payload for deferred payment scheme""" - - signature: str - voucher: DeferredEvmPayloadVoucher - - model_config = ConfigDict( - alias_generator=to_camel, - populate_by_name=True, - from_attributes=True, - ) - - -class DeferredPaymentRequirementsExtraNewVoucher(BaseModel): - """Extra data for creating a new deferred payment voucher""" - - type: Literal["new"] - voucher: dict # Contains only 'id' and 'escrow' fields - - model_config = ConfigDict( - alias_generator=to_camel, - populate_by_name=True, - from_attributes=True, - ) - - -class DeferredPaymentRequirementsExtraAggregationVoucher(BaseModel): - """Extra data for aggregating an existing deferred payment voucher""" - - type: Literal["aggregation"] - signature: str - voucher: DeferredEvmPayloadVoucher - - model_config = ConfigDict( - alias_generator=to_camel, - populate_by_name=True, - from_attributes=True, - ) - - # Union of payloads for each scheme -SchemePayloads = Union[ExactPaymentPayload, DeferredPaymentPayload] +SchemePayloads = ExactPaymentPayload class PaymentPayload(BaseModel): diff --git a/python/x402/tests/test_deferred.py b/python/x402/tests/test_deferred.py deleted file mode 100644 index 447369fa11..0000000000 --- a/python/x402/tests/test_deferred.py +++ /dev/null @@ -1,272 +0,0 @@ -import pytest -import time -from unittest.mock import patch -from eth_account import Account -from eth_utils import to_checksum_address - -from x402.deferred import ( - prepare_payment_header, - create_new_voucher, - aggregate_voucher, - sign_voucher, - verify_voucher, - sign_payment_header, - encode_payment, - decode_payment, - DEFERRED_SCHEME, - EXPIRY_TIME, -) -from x402.types import ( - PaymentRequirements, - DeferredEvmPayloadVoucher, -) - - -class TestDeferredPaymentScheme: - @pytest.fixture - def account(self): - """Create a test account.""" - return Account.from_key("0x" + "a" * 64) - - @pytest.fixture - def payment_requirements_new(self): - """Create payment requirements for a new voucher.""" - return PaymentRequirements( - scheme=DEFERRED_SCHEME, - network="base-sepolia", - max_amount_required="1000000000000000000", # 1 token - resource="/api/test", - description="Test API", - mime_type="application/json", - pay_to="0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - max_timeout_seconds=300, - asset="0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - extra={ - "type": "new", - "voucher": { - "id": "0x" + "1" * 64, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - } - } - ) - - @pytest.fixture - def existing_voucher(self, account): - """Create an existing voucher for aggregation tests.""" - return DeferredEvmPayloadVoucher( - id="0x" + "1" * 64, - buyer=account.address, - seller="0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - value_aggregate="1000000000000000000", - asset="0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - timestamp=int(time.time()) - 100, - nonce=1, - escrow="0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - chain_id=84532, - expiry=int(time.time()) + EXPIRY_TIME, - ) - - def test_create_new_voucher(self, account, payment_requirements_new): - """Test creating a new voucher.""" - voucher = create_new_voucher(account.address, payment_requirements_new) - - assert voucher.id == "0x" + "1" * 64 - assert voucher.buyer == to_checksum_address(account.address) - assert voucher.seller == to_checksum_address(payment_requirements_new.pay_to) - assert voucher.value_aggregate == payment_requirements_new.max_amount_required - assert voucher.asset == to_checksum_address(payment_requirements_new.asset) - assert voucher.nonce == 0 - assert voucher.escrow == to_checksum_address("0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27") - assert voucher.chain_id == 84532 # base-sepolia - assert voucher.timestamp > 0 - assert voucher.expiry > voucher.timestamp - - def test_sign_and_verify_voucher(self, account, existing_voucher): - """Test signing and verifying a voucher.""" - signature = sign_voucher(account, existing_voucher) - - assert signature.startswith("0x") - assert len(signature) == 132 # 0x + 130 hex chars - - # Verify with correct signer - assert verify_voucher(existing_voucher, signature, account.address) is True - - # Verify with wrong signer - wrong_account = Account.from_key("0x" + "b" * 64) - assert verify_voucher(existing_voucher, signature, wrong_account.address) is False - - def test_aggregate_voucher(self, account, existing_voucher): - """Test aggregating an existing voucher.""" - # Sign the existing voucher - signature = sign_voucher(account, existing_voucher) - - # Create payment requirements for aggregation - payment_requirements = PaymentRequirements( - scheme=DEFERRED_SCHEME, - network="base-sepolia", - max_amount_required="500000000000000000", # 0.5 token - resource="/api/test", - description="Test API", - mime_type="application/json", - pay_to=existing_voucher.seller, - max_timeout_seconds=300, - asset=existing_voucher.asset, - extra={ - "type": "aggregation", - "signature": signature, - "voucher": existing_voucher.model_dump(by_alias=True), - } - ) - - # Aggregate the voucher - aggregated = aggregate_voucher(account.address, payment_requirements) - - assert aggregated.id == existing_voucher.id - assert aggregated.buyer == to_checksum_address(account.address) - assert aggregated.seller == existing_voucher.seller - assert aggregated.value_aggregate == "1500000000000000000" # 1.5 tokens - assert aggregated.nonce == existing_voucher.nonce + 1 - assert aggregated.timestamp >= existing_voucher.timestamp - assert aggregated.expiry > aggregated.timestamp - - def test_aggregate_voucher_validation(self, account, existing_voucher): - """Test voucher aggregation validation.""" - signature = sign_voucher(account, existing_voucher) - - # Test with wrong seller - with pytest.raises(ValueError, match="Invalid voucher seller"): - payment_requirements = PaymentRequirements( - scheme=DEFERRED_SCHEME, - network="base-sepolia", - max_amount_required="500000000000000000", - resource="/api/test", - description="Test API", - mime_type="application/json", - pay_to="0x0000000000000000000000000000000000000001", # Wrong seller - max_timeout_seconds=300, - asset=existing_voucher.asset, - extra={ - "type": "aggregation", - "signature": signature, - "voucher": existing_voucher.model_dump(by_alias=True), - } - ) - aggregate_voucher(account.address, payment_requirements) - - # Test with wrong asset - with pytest.raises(ValueError, match="Invalid voucher asset"): - payment_requirements = PaymentRequirements( - scheme=DEFERRED_SCHEME, - network="base-sepolia", - max_amount_required="500000000000000000", - resource="/api/test", - description="Test API", - mime_type="application/json", - pay_to=existing_voucher.seller, - max_timeout_seconds=300, - asset="0x0000000000000000000000000000000000000002", # Wrong asset - extra={ - "type": "aggregation", - "signature": signature, - "voucher": existing_voucher.model_dump(by_alias=True), - } - ) - aggregate_voucher(account.address, payment_requirements) - - def test_prepare_payment_header(self, account, payment_requirements_new): - """Test preparing an unsigned payment header.""" - header = prepare_payment_header( - account.address, - 1, - payment_requirements_new - ) - - assert header["x402Version"] == 1 - assert header["scheme"] == DEFERRED_SCHEME - assert header["network"] == "base-sepolia" - assert header["payload"]["signature"] is None - assert header["payload"]["voucher"]["id"] == "0x" + "1" * 64 - assert header["payload"]["voucher"]["nonce"] == 0 - - def test_sign_payment_header(self, account, payment_requirements_new): - """Test signing a payment header.""" - header = prepare_payment_header( - account.address, - 1, - payment_requirements_new - ) - - encoded = sign_payment_header(account, payment_requirements_new, header) - - # Decode and verify - decoded = decode_payment(encoded) - assert decoded["x402Version"] == 1 - assert decoded["scheme"] == DEFERRED_SCHEME - assert decoded["payload"]["signature"].startswith("0x") - assert len(decoded["payload"]["signature"]) == 132 - - def test_expired_voucher(self, account): - """Test that expired vouchers are rejected.""" - # Create an expired voucher - expired_voucher = DeferredEvmPayloadVoucher( - id="0x" + "2" * 64, - buyer=account.address, - seller="0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - value_aggregate="1000000000000000000", - asset="0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - timestamp=int(time.time()) - 1000, - nonce=1, - escrow="0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - chain_id=84532, - expiry=int(time.time()) - 100, # Expired - ) - - signature = sign_voucher(account, expired_voucher) - - payment_requirements = PaymentRequirements( - scheme=DEFERRED_SCHEME, - network="base-sepolia", - max_amount_required="500000000000000000", - resource="/api/test", - description="Test API", - mime_type="application/json", - pay_to=expired_voucher.seller, - max_timeout_seconds=300, - asset=expired_voucher.asset, - extra={ - "type": "aggregation", - "signature": signature, - "voucher": expired_voucher.model_dump(by_alias=True), - } - ) - - with pytest.raises(ValueError, match="Voucher expired"): - aggregate_voucher(account.address, payment_requirements) - - def test_encode_decode_payment(self): - """Test encoding and decoding payment data.""" - payment_data = { - "x402Version": 1, - "scheme": DEFERRED_SCHEME, - "network": "base-sepolia", - "payload": { - "signature": "0x" + "a" * 130, - "voucher": { - "id": "0x" + "1" * 64, - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "1000000000000000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1234567890, - "nonce": 0, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1234567890 + EXPIRY_TIME, - } - } - } - - encoded = encode_payment(payment_data) - decoded = decode_payment(encoded) - - assert decoded == payment_data \ No newline at end of file From 797383bed0e2b44ad399dd0ae7833ab45ea690b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 14 Oct 2025 17:22:13 -0300 Subject: [PATCH 099/116] docs: update with latest deposit with auth changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- README.md | 15 +- specs/schemes/deferred/scheme_deferred_evm.md | 140 ++++++++++++++++-- .../scheme_deferred_evm_escrow_contract.md | 4 + .../scheme_deferred_evm_facilitator.md | 72 ++++++++- 4 files changed, 209 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index fb81be1fbb..c1be1cf3be 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ The `deferred` scheme modifies slightly the x402 protocol flow to allow for a de 3. `Client` creates a `Payment Payload` based on the value of the `paymentRequirements.extra` property: - If there is no previous `Client/Resource server` history, it will instruct the `Client` to create a new voucher as payload. - Otherwise it will contain the latest voucher for the pair, allowing the `Client` to aggregate payments on top of it before setting it as the payload. + - Optionally, the `Client` can sign a deposit authorization to allow the `facilitator server` to escrow funds on its behalf. 4. `Client` sends the HTTP request with the `X-PAYMENT` header containing the `Payment Payload` to the resource server. The payload will include: - the signed voucher (which can be new or an aggregation with a previous one) @@ -117,22 +118,22 @@ The `deferred` scheme modifies slightly the x402 protocol flow to allow for a de 6. `Facilitator server` performs verification of the object based on the `scheme` and `network` of the `Payment Payload` and returns a `Verification Response`. 7. If the `Verification Response` is valid: - - The resource server POSTs the validated voucher back to the `facilitator server` for peristent storage. - - The `facilitator server` will reverify the `Payment Payload` before storing the voucher, which makes the previous verification call optional. + - The resource server POSTs the validated voucher back to the `facilitator server` for persistent storage using the endpoint `POST /deferred/vouchers` + - The `facilitator server` will reverify the `Payment Payload` before storing the voucher, which makes the previous verification call optional (5. and 6.). - If a deposit authorization is present the `facilitator server` will execute it. - - Then the resource server performs the work to fulfill the original request. + - Then the resource server performs the work to fulfill the original request. If the `Verification Response` is invalid: - the resource server returns a `402 Payment Required` status and a `Payment Required Response` JSON object in the response body. 8. `Resource server` returns a `200 OK` response to the `Client` with the resource they requested as the body of the HTTP response, and a `X-PAYMENT-RESPONSE` header containing the total outstanding payment that is pending on-chain settlement. -At this point the `Client` has "payed for" the resource access by means of a signed voucher. The `facilitator server` stores the vouchers which can be redeemed at any time. The settlement sequencing then is as follows: +At this point the `Client` has "paid for" the resource access by means of a signed voucher. The `facilitator server` stores the vouchers which can be redeemed at any time. The settlement sequencing then is as follows: -1. `Resource server` requests a settlement to happen by POSTing to a special `facilitator server` endpoint. +1. `Resource server` requests a settlement to happen by POSTing to a special `facilitator server` endpoint: `POST /deferred/vouchers/settle` 2. `Facilitator server` retrieves the voucher to be settled and submits the transaction to the blockchain based on the `scheme` and `network` of the `Payment Payload`. -3. `Facilitator server` waits for the voucher settlment to be confirmed on the blockchain. +3. `Facilitator server` waits for the voucher settlement to be confirmed on the blockchain. 4. `Facilitator server` returns a `Payment Execution Response` to the resource server. @@ -191,7 +192,7 @@ At this point the `Client` has "payed for" the resource access by means of a sig // Extra information about the payment details specific to the scheme // For `exact` scheme on a EVM network, expects extra to contain the records `name` and `version` pertaining to asset - // For `deferred` scheme on a EVN network, expects extra to contain the records `type`, `voucher` and `signature` + // For `deferred` scheme on a EVM network, expects extra to contain the records `type`, `voucher` and `signature` extra: object | null; } ``` diff --git a/specs/schemes/deferred/scheme_deferred_evm.md b/specs/schemes/deferred/scheme_deferred_evm.md index d54287f29d..d6dd0582af 100644 --- a/specs/schemes/deferred/scheme_deferred_evm.md +++ b/specs/schemes/deferred/scheme_deferred_evm.md @@ -12,6 +12,7 @@ The `payload` field of the `X-PAYMENT` header must contain the following fields: - `signature`: The signature of the `EIP-712` voucher. - `voucher`: parameters required to reconstruct the signed message for the operation. +- `depositAuthorization` (optional): A signed authorization allowing the facilitator to deposit funds into escrow on behalf of the buyer. This enables gasless deposits for new buyers or when additional funds are needed. ### Voucher Fields @@ -46,7 +47,7 @@ Example: } ``` -Full `X-PAYMENT` header: +Full `X-PAYMENT` header (without deposit authorization): ```json { @@ -71,36 +72,129 @@ Full `X-PAYMENT` header: } ``` +### Deposit Authorization Fields (optional) + +The `depositAuthorization` object enables gasless escrow deposits by allowing the facilitator to execute deposits on behalf of the buyer. This is particularly useful for first-time buyers or when escrow balance needs to be topped up. The structure consists of two parts: + +**Required:** +- `depositAuthorization`: EIP-712 signed authorization for the escrow contract + - `buyer`: Address of the buyer authorizing the deposit (address) + - `seller`: Address of the seller receiving the escrow deposit (address) + - `asset`: ERC-20 token contract address (address) + - `amount`: Amount to deposit in atomic token units (uint256) + - `nonce`: Unique bytes32 for replay protection (bytes32) + - `expiry`: Authorization expiration timestamp (uint64) + - `signature`: EIP-712 signature of the deposit authorization (bytes) + +**Optional:** +- `permit`: EIP-2612 permit for the ERC-20 token (if token supports permits) + - `owner`: Token owner address (address) + - `spender`: Escrow contract address (address) + - `value`: Token amount to approve (uint256) + - `nonce`: Token contract nonce for the permit (uint256/bigint) + - `deadline`: Permit expiration timestamp (uint256) + - `domain`: Token's EIP-712 domain + - `name`: Token name (string) + - `version`: Token version (string) + - `signature`: EIP-2612 signature of the permit (bytes) + +Example `X-PAYMENT` header with deposit authorization: + +```json +{ + "x402Version": 1, + "scheme": "deferred", + "network": "base-sepolia", + "payload": { + "signature": "0x3a2f7e3b6c1d8e9c0f64f8724e5cfb8bfe9a3cdb1ad6e4a876f7d418e47e96b11a23346a1b0e60c8d3a4c4fd0150a244ab4b0e6d6c5fa4103f8fa8fd2870a3c81b", + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "2000000000000000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1740673000, + "nonce": 3, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1740759400 + }, + "depositAuthorization": { + "permit": { + "owner": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "spender": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "value": "5000000", + "nonce": "0", + "deadline": 1740759400, + "domain": { + "name": "USD Coin", + "version": "2" + }, + "signature": "0x8f9e2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f1b" + }, + "depositAuthorization": { + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "amount": "5000000", + "nonce": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", + "expiry": 1740759400, + "signature": "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" + } + } + } +} +``` + ## `paymentRequirements` extra object The `extra` object in the "Payment Required Response" should contain the following fields: -- A `type` field to indicate wether it's a new voucher or an aggregation -- If this is a new voucher being created: - - `voucher`: A simplified voucher object with: - - `id`: The voucher id - - `escrow`: The address of the escrow contract -- If an existing voucher is being aggregated: - - `signature`: The signature of the latest voucher corresponding to the given `id` - - `voucher`: The latest voucher corresponding to the given `id` -Example: +### Common Fields +- `type`: Indicates whether this is a `"new"` voucher or an `"aggregation"` of an existing voucher +- `account` (optional): Current escrow account details for the buyer-seller-asset tuple + - `balance`: Current escrow balance in atomic token units + - `assetAllowance`: Current token allowance for the escrow contract + - `assetPermitNonce`: Current permit nonce for the token contract + - `facilitator`: Address of the facilitator managing the escrow + +### For New Vouchers (`type: "new"`) +- `voucher`: A simplified voucher object containing: + - `id`: The voucher id to use for the new voucher (bytes32) + - `escrow`: The address of the escrow contract (address) + +### For Aggregation (`type: "aggregation"`) +- `signature`: The signature of the latest voucher corresponding to the given `id` (bytes) +- `voucher`: The complete latest voucher corresponding to the given `id` (all voucher fields) + +### Examples + +**New voucher (without account details):** ```json { - ... "extra": { "type": "new", "voucher": { "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27" } } } +``` +**Aggregation (with account details):** + +```json { - ... "extra": { "type": "aggregation", + "account": { + "balance": "5000000", + "assetAllowance": "5000000", + "assetPermitNonce": "0", + "facilitator": "https://facilitator.com" + }, "signature": "0x3a2f7e3b6c1d8e9c0f64f8724e5cfb8bfe9a3cdb1ad6e4a876f7d418e47e96b11a23346a1b0e60c8d3a4c4fd0150a244ab4b0e6d6c5fa4103f8fa8fd2870a3c81b", "voucher": { "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", @@ -142,9 +236,27 @@ The following steps are required to verify a deferred payment: 6. **Expiry validation**: - Verify the voucher has not expired by checking that the current timestamp is less than or equal to `expiry` - Verify `paymentPayload.voucher.expiry` and `paymentPayload.voucher.timestamp` dates make sense -7. **Transaction simulation** (optional but recommended): +7. **Deposit authorization validation** (if present): + - Verify the `depositAuthorization.depositAuthorization.signature` is a valid EIP-712 signature + - Verify `depositAuthorization.depositAuthorization.buyer` matches `paymentPayload.voucher.buyer` + - Verify `depositAuthorization.depositAuthorization.seller` matches `paymentPayload.voucher.seller` + - Verify `depositAuthorization.depositAuthorization.asset` matches `paymentPayload.voucher.asset` + - Verify `depositAuthorization.depositAuthorization.expiry` has not passed + - Verify the nonce has not been used before by checking the escrow contract + - If `permit` is present: + - Verify the `permit.signature` is a valid EIP-2612 signature + - Verify the permit nonce is valid by checking the token contract + - Verify `permit.owner` matches the buyer + - Verify `permit.spender` matches the escrow contract address + - Verify `permit.value` is sufficient to cover the deposit amount + - Verify `permit.deadline` has not passed +8. **Transaction simulation** (optional but recommended): - Simulate the voucher collection to ensure the transaction would succeed on-chain +## Deposit Authorization Execution + +When a `depositAuthorization` is included in the payment payload, the facilitator should execute it before storing the voucher. This ensures that the buyer has sufficient funds escrowed before the voucher is stored, preventing invalid vouchers from being accepted. + ## Settlement Settlement is performed via the facilitator calling the `collect` function on the escrow contract with the `payload.signature` and `payload.voucher` parameters from the `X-PAYMENT` header. This can be initiated by buyer's request or the facilitator holding the vouchers could trigger automatic settlement based on pre-agreed conditions. diff --git a/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md b/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md index 58d27e8f77..1ade49cf83 100644 --- a/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md +++ b/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md @@ -195,6 +195,10 @@ struct FlushAllAuthorization { ### View Functions - `getAccount(address buyer, address seller, address asset)` → `EscrowAccount` - Get escrow account details +- `getAccountDetails(address buyer, address seller, address asset, bytes32[] voucherIds, uint256[] valueAggregates)` → `(uint256 balance, uint256 allowance, uint256 nonce)` - Get account details including available balance after accounting for pending vouchers, token allowance, and permit nonce. Returns: + - `balance`: Available escrow balance minus thawing amount and minus amounts needed for the provided voucher collections + - `allowance`: Current token allowance granted to the escrow contract + - `nonce`: Current EIP-2612 permit nonce for the buyer on the asset token contract - `getVoucherCollected(address buyer, address seller, address asset, bytes32 voucherId)` → `uint256` - Get total amount already collected for this voucher ID - `getOutstandingAndCollectableAmount(Voucher voucher)` → `(uint256 outstanding, uint256 collectable)` - Returns outstanding amount still owed and amount that can be collected immediately given current escrow balance - `isVoucherSignatureValid(Voucher voucher, bytes signature)` → `bool` - Validate voucher signature diff --git a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md index 7c61f1ded8..2181a27c31 100644 --- a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md +++ b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md @@ -42,7 +42,13 @@ Returns the most suitable voucher for aggregation between a buyer-seller pair. Stores a new signed voucher in the facilitator's voucher store after verifying it. The verification should be exactly the same as you'd get by POSTing to /verify. This allows for replacing that call for one to this endpoint. -**Request Body:** +If the payment payload contains a `depositAuthorization`, the facilitator must execute it **before** storing the voucher: +1. If a `permit` is present, call the token contract's `permit` function +2. Call the escrow contract's `depositWithAuthorization` function +3. Verify the deposit succeeded by checking the escrow balance +4. Only then store the voucher + +**Request Body (without depositAuthorization):** ```json { "paymentPayload": { @@ -92,6 +98,70 @@ Stores a new signed voucher in the facilitator's voucher store after verifying i } ``` +**Request Body (with depositAuthorization):** +```json +{ + "paymentPayload": { + "x402Version": 1, + "network": "base-sepolia", + "scheme": "deferred", + "payload": { + "signature": "0x4b3f8e...", + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "1000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1740673000, + "nonce": 1, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1740759400 + }, + "depositAuthorization": { + "permit": { + "owner": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "spender": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "value": "5000000", + "nonce": "0", + "deadline": 1740759400, + "domain": { + "name": "USD Coin", + "version": "2" + }, + "signature": "0x8f9e2a3b..." + }, + "depositAuthorization": { + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "amount": "5000000", + "nonce": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", + "expiry": 1740759400, + "signature": "0xbfdc3d0a..." + } + } + } + }, + "paymentRequirements": { + "x402Version": 1, + "network": "base-sepolia", + "scheme": "deferred", + "recipient": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "amount": "1000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "extra": { + "type": "new", + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27" + } + } + } +} +``` + **Response (201 Created):** ```json { From fc26594f329448d80fd39e48366d4cd6363230b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 15 Oct 2025 12:29:03 -0300 Subject: [PATCH 100/116] feat(deferred): add escrow flushing functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/schemes/deferred/evm/client.ts | 9 +- .../schemes/deferred/evm/facilitator.test.ts | 150 +++++++++++++++- .../src/schemes/deferred/evm/facilitator.ts | 82 ++++++++- .../src/schemes/deferred/evm/sign.test.ts | 163 ++++++++++++++++-- .../x402/src/schemes/deferred/evm/sign.ts | 100 ++++++++++- .../src/schemes/deferred/evm/verify.test.ts | 120 ++++++++++++- .../x402/src/schemes/deferred/evm/verify.ts | 60 ++++++- .../x402/src/types/shared/evm/typedData.ts | 8 + .../x402/src/types/verify/schemes/deferred.ts | 36 ++++ .../x402/src/verify/useDeferred.test.ts | 126 ++++++++++++++ .../packages/x402/src/verify/useDeferred.ts | 47 ++++- 11 files changed, 861 insertions(+), 40 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index b5eb9f9b30..2e73c10f3b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -15,7 +15,12 @@ import { UnsignedDeferredPaymentPayload, UnsignedDeferredPaymentPayloadSchema, } from "../../../types/verify/schemes/deferred"; -import { signPermit, signDepositAuthorizationInner, signVoucher, verifyVoucher } from "./sign"; +import { + signPermit, + signDepositAuthorizationInner, + signVoucher, + verifyVoucherSignature, +} from "./sign"; import { encodePayment } from "./utils/paymentUtils"; import { getUsdcChainConfigForChain } from "../../../shared/evm"; import { randomBytes } from "node:crypto"; @@ -126,7 +131,7 @@ export async function aggregateVoucher( } // verify signature is valid and the voucher's buyer is the client - const isValid = await verifyVoucher(extra.voucher, extra.signature as Hex, buyer); + const isValid = await verifyVoucherSignature(extra.voucher, extra.signature as Hex, buyer); if (!isValid) { throw new Error("Invalid voucher signature"); } diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts index a6ecff2b55..05f5b2121b 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { Address, Chain, Log, Transport } from "viem"; +import { Address, Chain, Log, TransactionReceipt, Transport } from "viem"; import { createSigner, ConnectedClient, SignerWallet } from "../../../types/shared/evm"; import { PaymentRequirements, SchemeContext } from "../../../types/verify"; import { DeferredPaymentPayload, DEFERRRED_SCHEME } from "../../../types/verify/schemes/deferred"; @@ -8,6 +8,7 @@ import { settle, settleVoucher, depositWithAuthorization, + flushWithAuthorization, getEscrowAccountDetails, } from "./facilitator"; import { VoucherStore } from "./store"; @@ -17,10 +18,11 @@ import * as verifyModule from "./verify"; vi.mock("./verify", () => ({ verifyPaymentRequirements: vi.fn(), verifyVoucherContinuity: vi.fn(), - verifyVoucherSignature: vi.fn(), + verifyVoucherSignatureWrapper: vi.fn(), verifyVoucherAvailability: vi.fn(), verifyOnchainState: vi.fn(), verifyDepositAuthorization: vi.fn(), + verifyFlushAuthorization: vi.fn(), })); const buyer = createSigner( @@ -115,7 +117,7 @@ describe("facilitator - verify", () => { // Mock all verification functions to return success by default vi.mocked(verifyModule.verifyPaymentRequirements).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherContinuity).mockReturnValue({ isValid: true }); - vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherSignatureWrapper).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); }); @@ -180,7 +182,7 @@ describe("facilitator - verify", () => { }); it("should return invalid response when voucher signature verification fails", async () => { - vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ + vi.mocked(verifyModule.verifyVoucherSignatureWrapper).mockResolvedValue({ isValid: false, invalidReason: "invalid_deferred_evm_payload_signature", payer: buyerAddress, @@ -307,7 +309,7 @@ describe("facilitator - settle", () => { // Mock successful verification by default vi.mocked(verifyModule.verifyPaymentRequirements).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherContinuity).mockReturnValue({ isValid: true }); - vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherSignatureWrapper).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); @@ -409,7 +411,7 @@ describe("facilitator - settleVoucher", () => { } as unknown as VoucherStore; // Mock successful verification by default - vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherSignatureWrapper).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); @@ -485,7 +487,7 @@ describe("facilitator - settleVoucher", () => { }); it("should return error when voucher signature verification fails", async () => { - vi.mocked(verifyModule.verifyVoucherSignature).mockResolvedValue({ + vi.mocked(verifyModule.verifyVoucherSignatureWrapper).mockResolvedValue({ isValid: false, invalidReason: "invalid_deferred_evm_payload_signature", }); @@ -1188,3 +1190,137 @@ describe("facilitator - getEscrowAccountDetails", () => { ); }); }); + +describe("facilitator - flushWithAuthorization", () => { + const mockFlushAuthorization = { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" as `0x${string}`, + }; + + let mockWallet: SignerWallet; + + beforeEach(() => { + vi.clearAllMocks(); + + // Mock successful verification by default + vi.mocked(verifyModule.verifyFlushAuthorization).mockResolvedValue({ isValid: true }); + + // Create a proper mock wallet with all required properties + mockWallet = { + account: { + address: buyerAddress, + }, + chain: { id: 84532 }, + readContract: vi.fn(), + writeContract: vi.fn().mockResolvedValue("0x1234567890abcdef"), + waitForTransactionReceipt: vi.fn().mockResolvedValue({ + status: "success", + logs: [], + }), + } as unknown as SignerWallet; + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it("should flush with authorization successfully", async () => { + const result = await flushWithAuthorization( + mockWallet, + mockFlushAuthorization, + escrowAddress as `0x${string}`, + ); + + expect(result).toEqual({ + success: true, + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + + // Should have called writeContract once (flushWithAuthorization) + expect(mockWallet.writeContract).toHaveBeenCalledTimes(1); + + // Verify flushWithAuthorization call + const flushCall = vi.mocked(mockWallet.writeContract).mock.calls[0][0]; + expect(flushCall).toMatchObject({ + address: escrowAddress, + functionName: "flushWithAuthorization", + }); + + // Verify the args structure + expect(flushCall.args?.[0]).toMatchObject({ + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + nonce: mockFlushAuthorization.nonce, + }); + expect((flushCall.args?.[0] as { expiry: bigint }).expiry).toBe( + BigInt(mockFlushAuthorization.expiry), + ); + expect(flushCall.args?.[1]).toBe(mockFlushAuthorization.signature); + }); + + it("should return error if flush authorization verification fails", async () => { + vi.mocked(verifyModule.verifyFlushAuthorization).mockResolvedValue({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_flush_authorization_signature", + }); + + const result = await flushWithAuthorization( + mockWallet, + mockFlushAuthorization, + escrowAddress as `0x${string}`, + ); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_deferred_evm_payload_flush_authorization_signature", + transaction: "", + payer: buyerAddress, + }); + + expect(mockWallet.writeContract).not.toHaveBeenCalled(); + }); + + it("should return error when flushWithAuthorization transaction reverts", async () => { + vi.mocked(mockWallet.writeContract).mockRejectedValueOnce(new Error("Flush failed")); + + const result = await flushWithAuthorization( + mockWallet, + mockFlushAuthorization, + escrowAddress as `0x${string}`, + ); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_transaction_reverted", + transaction: "", + payer: buyerAddress, + }); + }); + + it("should return error when flushWithAuthorization transaction has failed status", async () => { + vi.mocked(mockWallet.waitForTransactionReceipt).mockResolvedValueOnce({ + status: "reverted", + logs: [], + } as unknown as TransactionReceipt); + + const result = await flushWithAuthorization( + mockWallet, + mockFlushAuthorization, + escrowAddress as `0x${string}`, + ); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_transaction_state", + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + }); +}); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 9069b67573..521797e787 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -22,7 +22,9 @@ import { DeferredDepositWithAuthorizationResponse, DeferredErrorResponse, DeferredEscrowDepositAuthorization, + DeferredEscrowFlushAuthorizationSigned, DeferredEvmPayloadVoucher, + DeferredFlushWithAuthorizationResponse, DeferredPaymentPayloadSchema, DeferredPaymentRequirementsSchema, DeferredSchemeContextSchema, @@ -31,11 +33,12 @@ import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; import { usdcABI } from "../../../types/shared/evm/erc20PermitABI"; import { verifyPaymentRequirements, - verifyVoucherSignature, + verifyVoucherSignatureWrapper, verifyOnchainState, verifyVoucherContinuity, verifyVoucherAvailability, verifyDepositAuthorization, + verifyFlushAuthorization, } from "./verify"; import { VoucherStore } from "./store"; @@ -82,7 +85,7 @@ export async function verify< } // Verify voucher signature is valid - const signatureResult = await verifyVoucherSignature( + const signatureResult = await verifyVoucherSignatureWrapper( paymentPayload.payload.voucher, paymentPayload.payload.signature, ); @@ -213,7 +216,7 @@ export async function settleVoucher { // Verify the voucher signature - const signatureResult = await verifyVoucherSignature(voucher, signature); + const signatureResult = await verifyVoucherSignatureWrapper(voucher, signature); if (!signatureResult.isValid) { return { success: false, @@ -515,3 +518,76 @@ export async function getEscrowAccountDetails< assetPermitNonce: nonce.toString(), }; } + +/** + * Flushes an escrow account using a signed flush authorization + * + * This function performs a flush operation which: + * 1. Withdraws any funds that have completed their thawing period (ready to withdraw) + * 2. Initiates thawing for any remaining balance that isn't already thawing + * + * @param wallet - The facilitator wallet that will submit the transaction + * @param flushAuthorization - The signed flush authorization from the buyer + * @param escrow - The address of the escrow contract + * @returns A response containing the transaction status and hash + */ +export async function flushWithAuthorization( + wallet: SignerWallet, + flushAuthorization: DeferredEscrowFlushAuthorizationSigned, + escrow: Address, +): Promise { + // Verify the flush authorization + const valid = await verifyFlushAuthorization(flushAuthorization, escrow, wallet.chain.id); + if (!valid.isValid) { + return { + success: false, + errorReason: valid.invalidReason ?? "invalid_deferred_evm_payload_flush_authorization_failed", + transaction: "", + payer: flushAuthorization.buyer, + }; + } + + let tx = ""; + try { + tx = await wallet.writeContract({ + address: escrow as Address, + abi: deferredEscrowABI, + functionName: "flushWithAuthorization" as const, + args: [ + { + buyer: getAddress(flushAuthorization.buyer), + seller: getAddress(flushAuthorization.seller), + asset: getAddress(flushAuthorization.asset), + nonce: flushAuthorization.nonce as `0x${string}`, + expiry: BigInt(flushAuthorization.expiry), + }, + flushAuthorization.signature as `0x${string}`, + ], + chain: wallet.chain as Chain, + }); + } catch (error) { + console.error(error); + return { + success: false, + errorReason: "invalid_transaction_reverted", + transaction: "", + payer: flushAuthorization.buyer, + }; + } + + const receipt = await wallet.waitForTransactionReceipt({ hash: tx as `0x${string}` }); + if (receipt.status !== "success") { + return { + success: false, + errorReason: "invalid_transaction_state", + transaction: tx, + payer: flushAuthorization.buyer, + }; + } + + return { + success: true, + transaction: tx, + payer: flushAuthorization.buyer, + }; +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts index 0aa7f0da5d..cbad507308 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.test.ts @@ -2,11 +2,13 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createSigner } from "../../../types/shared/evm"; import { signVoucher, - verifyVoucher, + verifyVoucherSignature, signPermit, - verifyPermit, + verifyPermitSignature, signDepositAuthorizationInner, - verifyDepositAuthorizationInner, + verifyDepositAuthorizationInnerSignature, + signFlushAuthorization, + verifyFlushAuthorizationSignature, } from "./sign"; import { privateKeyToAccount } from "viem/accounts"; @@ -55,12 +57,16 @@ describe("voucher signature", () => { }); it("should verify a valid voucher signature", async () => { - const isValid = await verifyVoucher(mockVoucher, mockVoucherSignature, buyerAddress); + const isValid = await verifyVoucherSignature(mockVoucher, mockVoucherSignature, buyerAddress); expect(isValid).toBe(true); }); it("should return false if voucher signature is valid but for a different buyer", async () => { - const isValid = await verifyVoucher(mockVoucher, mockVoucherSignature, anotherBuyerAddress); + const isValid = await verifyVoucherSignature( + mockVoucher, + mockVoucherSignature, + anotherBuyerAddress, + ); expect(isValid).toBe(false); }); @@ -79,7 +85,11 @@ describe("voucher signature", () => { ); const signature = await signVoucher(localAccount, mockVoucher); - const isValid = await verifyVoucher(mockVoucher, signature.signature, localAccount.address); + const isValid = await verifyVoucherSignature( + mockVoucher, + signature.signature, + localAccount.address, + ); expect(isValid).toBe(true); }); @@ -114,7 +124,7 @@ describe("permit signature", () => { owner: buyerAddress, spender: escrowAddress, value: "1000000", - nonce: 0, + nonce: "0", deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days domain: { name: "USD Coin", @@ -141,7 +151,7 @@ describe("permit signature", () => { }); it("should verify a valid permit signature", async () => { - const isValid = await verifyPermit( + const isValid = await verifyPermitSignature( mockPermit, mockPermitSignature as `0x${string}`, buyerAddress as `0x${string}`, @@ -152,7 +162,7 @@ describe("permit signature", () => { }); it("should return false if permit signature is valid but for a different signer", async () => { - const isValid = await verifyPermit( + const isValid = await verifyPermitSignature( mockPermit, mockPermitSignature as `0x${string}`, anotherBuyerAddress as `0x${string}`, @@ -187,7 +197,7 @@ describe("permit signature", () => { assetAddress as `0x${string}`, ); - const isValid = await verifyPermit( + const isValid = await verifyPermitSignature( mockPermit, signature.signature, localAccount.address, @@ -255,7 +265,7 @@ describe("deposit authorization signature", () => { }); it("should verify a valid deposit authorization signature", async () => { - const isValid = await verifyDepositAuthorizationInner( + const isValid = await verifyDepositAuthorizationInnerSignature( mockDepositAuth, mockDepositAuthSignature as `0x${string}`, buyerAddress as `0x${string}`, @@ -266,7 +276,7 @@ describe("deposit authorization signature", () => { }); it("should return false if deposit authorization signature is valid but for a different signer", async () => { - const isValid = await verifyDepositAuthorizationInner( + const isValid = await verifyDepositAuthorizationInnerSignature( mockDepositAuth, mockDepositAuthSignature as `0x${string}`, anotherBuyerAddress as `0x${string}`, @@ -301,7 +311,7 @@ describe("deposit authorization signature", () => { escrowAddress as `0x${string}`, ); - const isValid = await verifyDepositAuthorizationInner( + const isValid = await verifyDepositAuthorizationInnerSignature( mockDepositAuth, signature.signature, localAccount.address, @@ -344,3 +354,130 @@ describe("deposit authorization signature", () => { ).rejects.toThrow("Invalid wallet client provided does not support signTypedData"); }); }); + +describe("flush authorization signature", () => { + const mockFlushAuth = { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days + }; + + beforeEach(() => { + vi.useFakeTimers(); + // Set a fixed time for consistent testing + vi.setSystemTime(new Date("2024-01-01T00:00:00Z")); + vi.clearAllMocks(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it("should create a valid flush authorization signature", async () => { + const signature = await signFlushAuthorization( + buyer, + mockFlushAuth, + 84532, + escrowAddress as `0x${string}`, + ); + expect(signature.signature).toBeDefined(); + expect(signature.signature).toMatch(/^0x[0-9a-fA-F]{130}$/); + }); + + it("should verify a valid flush authorization signature", async () => { + const signature = await signFlushAuthorization( + buyer, + mockFlushAuth, + 84532, + escrowAddress as `0x${string}`, + ); + + const isValid = await verifyFlushAuthorizationSignature( + mockFlushAuth, + signature.signature, + buyerAddress as `0x${string}`, + 84532, + escrowAddress as `0x${string}`, + ); + expect(isValid).toBe(true); + }); + + it("should return false if flush authorization signature is valid but for a different signer", async () => { + const signature = await signFlushAuthorization( + buyer, + mockFlushAuth, + 84532, + escrowAddress as `0x${string}`, + ); + + const isValid = await verifyFlushAuthorizationSignature( + mockFlushAuth, + signature.signature, + anotherBuyerAddress as `0x${string}`, + 84532, + escrowAddress as `0x${string}`, + ); + expect(isValid).toBe(false); + }); + + it("should sign a flush authorization using a LocalAccount", async () => { + const localAccount = privateKeyToAccount( + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const signature = await signFlushAuthorization( + localAccount, + mockFlushAuth, + 84532, + escrowAddress as `0x${string}`, + ); + + expect(signature.signature).toBeDefined(); + expect(signature.signature).toMatch(/^0x[0-9a-fA-F]{130}$/); + }); + + it("should verify a flush authorization signed by a LocalAccount", async () => { + const localAccount = privateKeyToAccount( + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + const signature = await signFlushAuthorization( + localAccount, + mockFlushAuth, + 84532, + escrowAddress as `0x${string}`, + ); + + const isValid = await verifyFlushAuthorizationSignature( + mockFlushAuth, + signature.signature, + localAccount.address, + 84532, + escrowAddress as `0x${string}`, + ); + expect(isValid).toBe(true); + }); + + it("should throw error if wallet client does not support signTypedData", async () => { + const invalidWallet = { + account: { address: buyerAddress }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + + await expect( + signFlushAuthorization(invalidWallet, mockFlushAuth, 84532, escrowAddress as `0x${string}`), + ).rejects.toThrow("Invalid wallet client provided does not support signTypedData"); + }); + + it("should throw error if LocalAccount does not support signTypedData", async () => { + const invalidAccount = { + address: buyerAddress, + type: "local", + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + + await expect( + signFlushAuthorization(invalidAccount, mockFlushAuth, 84532, escrowAddress as `0x${string}`), + ).rejects.toThrow("Invalid wallet client provided does not support signTypedData"); + }); +}); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts index 88193bbad4..35946b3749 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/sign.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/sign.ts @@ -8,10 +8,12 @@ import { createConnectedClient, permitPrimaryType, depositAuthorizationPrimaryType, + flushAuthorizationPrimaryType, } from "../../../types/shared/evm"; import { DeferredEscrowDepositAuthorizationInner, DeferredEscrowDepositAuthorizationPermit, + DeferredEscrowFlushAuthorization, DeferredEvmPayloadVoucher, } from "../../../types/verify/schemes/deferred"; import { getNetworkName } from "../../../shared"; @@ -75,7 +77,7 @@ export async function signVoucher( + walletClient: SignerWallet | LocalAccount, + flushAuthorization: DeferredEscrowFlushAuthorization, + chainId: number, + escrow: Address, +): Promise<{ signature: Hex }> { + const { buyer, seller, asset, nonce, expiry } = flushAuthorization; + const data = { + types: typedDataTypes, + primaryType: flushAuthorizationPrimaryType, + domain: { + name: "DeferredPaymentEscrow", + version: "1", + chainId: chainId, + verifyingContract: getAddress(escrow), + }, + message: { + buyer: getAddress(buyer), + seller: getAddress(seller), + asset: getAddress(asset), + nonce, + expiry, + }, + }; + + if (isSignerWallet(walletClient)) { + const signature = await walletClient.signTypedData(data); + return { + signature, + }; + } else if (isAccount(walletClient) && walletClient.signTypedData) { + const signature = await walletClient.signTypedData(data); + return { + signature, + }; + } else { + throw new Error("Invalid wallet client provided does not support signTypedData"); + } +} + +/** + * Verifies a flush authorization signature + * + * @param flushAuthorization - The flush authorization to verify + * @param signature - The signature to verify + * @param signer - The address of the signer to verify + * @param chainId - The chain ID + * @param escrow - The address of the escrow contract + * @returns The address that signed the authorization + */ +export async function verifyFlushAuthorizationSignature( + flushAuthorization: DeferredEscrowFlushAuthorization, + signature: Hex, + signer: Address, + chainId: number, + escrow: Address, +) { + const flushAuthorizationTypedData = { + types: typedDataTypes, + primaryType: flushAuthorizationPrimaryType, + domain: { + name: "DeferredPaymentEscrow", + version: "1", + chainId: chainId, + verifyingContract: getAddress(escrow), + }, + message: { + buyer: getAddress(flushAuthorization.buyer), + seller: getAddress(flushAuthorization.seller), + asset: getAddress(flushAuthorization.asset), + nonce: flushAuthorization.nonce, + expiry: flushAuthorization.expiry, + }, + }; + + const client = createConnectedClient(getNetworkName(chainId)); + return await client.verifyTypedData({ + address: signer, + ...flushAuthorizationTypedData, + signature: signature as Hex, + }); +} diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts index 051c83a631..2d6562aa25 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { PaymentRequirements } from "../../../types"; +import { DeferredEscrowFlushAuthorizationSigned, PaymentRequirements } from "../../../types"; import { DeferredPaymentPayload, DeferredPaymentRequirements, @@ -8,12 +8,13 @@ import { } from "../../../types/verify/schemes/deferred"; import { verifyPaymentRequirements, - verifyVoucherSignature, + verifyVoucherSignatureWrapper, verifyOnchainState, verifyVoucherContinuity, verifyVoucherAvailability, verifyVoucherDuplicate, verifyDepositAuthorization, + verifyFlushAuthorization, } from "./verify"; import { ConnectedClient, createSigner } from "../../../types/shared/evm/wallet"; import { getNetworkId } from "../../../shared"; @@ -738,12 +739,15 @@ describe("verifyVoucherSignature", async () => { const { signature } = await signVoucher(buyer, mockPaymentPayload.payload.voucher); it("should return isValid: true for valid voucher signature", async () => { - const result = await verifyVoucherSignature(mockPaymentPayload.payload.voucher, signature); + const result = await verifyVoucherSignatureWrapper( + mockPaymentPayload.payload.voucher, + signature, + ); expect(result).toEqual({ isValid: true }); }); it("should return isValid: false for invalid voucher signature", async () => { - const result = await verifyVoucherSignature( + const result = await verifyVoucherSignatureWrapper( mockPaymentPayload.payload.voucher, "0x999b52ba76bebfc79405b67d9004ed769a998b34a6be8695c265f32fee56b1a903f563f2abe1e02cc022e332e2cef2c146fb057567316966303480afdd88aff11c", ); @@ -1441,3 +1445,111 @@ describe("verifyDepositAuthorization", () => { }); }); }); + +describe("verifyFlushAuthorization", () => { + let mockFlushAuthorization: DeferredEscrowFlushAuthorizationSigned; + + beforeEach(async () => { + vi.clearAllMocks(); + vi.useFakeTimers(); + vi.setSystemTime(new Date(1715769600 * 1000 + 100000)); // 100 seconds after timestamp + + // Import signFlushAuthorization to generate a valid signature + const { signFlushAuthorization } = await import("./sign"); + const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + + const flushAuthBase = { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days + }; + + const { signature } = await signFlushAuthorization( + buyer, + flushAuthBase, + 84532, + escrowAddress as `0x${string}`, + ); + + mockFlushAuthorization = { + ...flushAuthBase, + signature, + }; + }); + + afterEach(() => { + vi.useRealTimers(); + vi.resetAllMocks(); + }); + + it("should return valid if flush authorization is valid", async () => { + const result = await verifyFlushAuthorization( + mockFlushAuthorization, + escrowAddress as `0x${string}`, + 84532, + ); + expect(result).toEqual({ isValid: true }); + }); + + it("should return error if flush authorization signature is invalid", async () => { + const invalidFlushAuth = { + ...mockFlushAuthorization, + signature: "0xinvalidsignature" as `0x${string}`, + }; + + const result = await verifyFlushAuthorization( + invalidFlushAuth, + escrowAddress as `0x${string}`, + 84532, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_flush_authorization_signature", + payer: buyerAddress, + }); + }); + + it("should return error if flush authorization is expired", async () => { + const { signFlushAuthorization } = await import("./sign"); + const buyer = createSigner( + "base-sepolia", + "0xcb160425c35458024591e64638d6f7720dac915a0fb035c5964f6d51de0987d9", + ); + + const expiredFlushAuthBase = { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 - 1000, // expired + }; + + const { signature } = await signFlushAuthorization( + buyer, + expiredFlushAuthBase, + 84532, + escrowAddress as `0x${string}`, + ); + + const expiredFlushAuth = { + ...expiredFlushAuthBase, + signature, + }; + + const result = await verifyFlushAuthorization( + expiredFlushAuth, + escrowAddress as `0x${string}`, + 84532, + ); + expect(result).toEqual({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_flush_authorization_continuity", + payer: buyerAddress, + }); + }); +}); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index d969ab99ed..33ca248794 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -6,10 +6,16 @@ import { DeferredPaymentPayload, DeferredPaymentRequirements, DEFERRRED_SCHEME, + DeferredEscrowFlushAuthorizationSigned, } from "../../../types/verify/schemes/deferred"; import { DeferredEscrowDepositAuthorization, VerifyResponse } from "../../../types"; import { getNetworkId } from "../../../shared"; -import { verifyDepositAuthorizationInner, verifyPermit, verifyVoucher } from "./sign"; +import { + verifyDepositAuthorizationInnerSignature, + verifyPermitSignature, + verifyVoucherSignature, + verifyFlushAuthorizationSignature, +} from "./sign"; import { ConnectedClient } from "../../../types/shared/evm/wallet"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; import { usdcABI } from "../../../types/shared/evm/erc20PermitABI"; @@ -253,11 +259,11 @@ export function verifyVoucherContinuity( * @param signature - The signature of the voucher * @returns Verification result */ -export async function verifyVoucherSignature( +export async function verifyVoucherSignatureWrapper( voucher: DeferredEvmPayloadVoucher, signature: string, ): Promise { - const voucherSignatureIsValid = await verifyVoucher( + const voucherSignatureIsValid = await verifyVoucherSignature( voucher, signature as Hex, voucher.buyer as Address, @@ -495,7 +501,7 @@ export async function verifyDepositAuthorization< // Verify the permit signature if (permit) { - const isPermitValid = await verifyPermit( + const isPermitValid = await verifyPermitSignature( permit, permit.signature as Hex, permit.owner as Address, @@ -525,7 +531,7 @@ export async function verifyDepositAuthorization< } // Verify deposit authorization signature - const isDepositAuthorizationValid = await verifyDepositAuthorizationInner( + const isDepositAuthorizationValid = await verifyDepositAuthorizationInnerSignature( depositAuthorizationInner, depositAuthorizationInner.signature as Hex, depositAuthorizationInner.buyer as Address, @@ -648,3 +654,47 @@ export async function verifyDepositAuthorization< isValid: true, }; } + +/** + * Verifies a flush authorization is valid. Checks the signature of the flush authorization. + * + * @param flushAuthorization - The flush authorization to verify + * @param escrow - The address of the escrow contract + * @param chainId - The chain ID + * @returns Verification result + */ +export async function verifyFlushAuthorization( + flushAuthorization: DeferredEscrowFlushAuthorizationSigned, + escrow: Address, + chainId: number, +): Promise { + // Verify flush authorization signature + const isFlushAuthorizationValid = await verifyFlushAuthorizationSignature( + flushAuthorization, + flushAuthorization.signature as Hex, + flushAuthorization.buyer as Address, + chainId, + escrow, + ); + if (!isFlushAuthorizationValid) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_flush_authorization_signature", + payer: flushAuthorization.buyer, + }; + } + + // Verify flush authorization continuity + const DATE_NOW = Math.floor(Date.now() / 1000); + if (flushAuthorization.expiry < DATE_NOW) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_flush_authorization_continuity", + payer: flushAuthorization.buyer, + }; + } + + return { + isValid: true, + }; +} diff --git a/typescript/packages/x402/src/types/shared/evm/typedData.ts b/typescript/packages/x402/src/types/shared/evm/typedData.ts index 481d72aff0..941d1ba8c7 100644 --- a/typescript/packages/x402/src/types/shared/evm/typedData.ts +++ b/typescript/packages/x402/src/types/shared/evm/typedData.ts @@ -34,9 +34,17 @@ export const typedDataTypes = { { name: "nonce", type: "bytes32" }, { name: "expiry", type: "uint64" }, ], + FlushAuthorization: [ + { name: "buyer", type: "address" }, + { name: "seller", type: "address" }, + { name: "asset", type: "address" }, + { name: "nonce", type: "bytes32" }, + { name: "expiry", type: "uint64" }, + ], }; export const transferWithAuthorizationPrimaryType = "TransferWithAuthorization" as const; export const deferredVoucherPrimaryType = "Voucher" as const; export const permitPrimaryType = "Permit" as const; export const depositAuthorizationPrimaryType = "DepositAuthorization" as const; +export const flushAuthorizationPrimaryType = "FlushAuthorization" as const; diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 5b45ea693a..066d7bef29 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -56,6 +56,9 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_deposit_authorization_buyer_mismatch", "invalid_deferred_evm_contract_call_failed_allowance", "invalid_deferred_evm_payload_deposit_authorization_insufficient_allowance", + "invalid_deferred_evm_payload_flush_authorization_signature", + "invalid_deferred_evm_payload_flush_authorization_continuity", + "invalid_deferred_evm_payload_flush_authorization_failed", ] as const; // x402DeferredEvmPayloadVoucher @@ -147,6 +150,27 @@ export type DeferredEscrowDepositAuthorization = z.infer< typeof DeferredEscrowDepositAuthorizationSchema >; +// x402DeferredEscrowFlushAuthorization +export const DeferredEscrowFlushAuthorizationSchema = z.object({ + buyer: z.string().regex(EvmAddressRegex), + seller: z.string().regex(EvmAddressRegex), + asset: z.string().regex(EvmAddressRegex), + nonce: z.string().regex(HexEncoded64ByteRegex), + expiry: z.number().int().nonnegative(), +}); +export type DeferredEscrowFlushAuthorization = z.infer< + typeof DeferredEscrowFlushAuthorizationSchema +>; + +// x402DeferredEscrowFlushAuthorizationSigned +export const DeferredEscrowFlushAuthorizationSignedSchema = + DeferredEscrowFlushAuthorizationSchema.extend({ + signature: z.string().regex(EvmSignatureRegex), + }); +export type DeferredEscrowFlushAuthorizationSigned = z.infer< + typeof DeferredEscrowFlushAuthorizationSignedSchema +>; + // x402DeferredEscrowDepositAuthorizationConfig export const DeferredEscrowDepositAuthorizationConfigSchema = z.object({ asset: z.string().regex(EvmAddressRegex), @@ -303,6 +327,18 @@ export type DeferredDepositWithAuthorizationResponse = z.infer< typeof DeferredDepositWithAuthorizationResponseSchema >; +// x402DeferredFlushWithAuthorizationResponse +export const DeferredFlushWithAuthorizationResponseSchema = z.object({ + success: z.boolean(), + errorReason: z.string().optional(), + payer: z.string().regex(EvmAddressRegex).optional(), + transaction: z.string().regex(EvmTransactionHashRegex), + network: NetworkSchema.optional(), +}); +export type DeferredFlushWithAuthorizationResponse = z.infer< + typeof DeferredFlushWithAuthorizationResponseSchema +>; + // x402DeferredAccountDetailsResponse export const DeferredAccountDetailsResponseSchema = z.object({ balance: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), diff --git a/typescript/packages/x402/src/verify/useDeferred.test.ts b/typescript/packages/x402/src/verify/useDeferred.test.ts index 485f51e732..50d1ed46a1 100644 --- a/typescript/packages/x402/src/verify/useDeferred.test.ts +++ b/typescript/packages/x402/src/verify/useDeferred.test.ts @@ -59,6 +59,7 @@ describe("useDeferredFacilitator", () => { expect(facilitator).toHaveProperty("verifyVoucher"); expect(facilitator).toHaveProperty("settleVoucher"); expect(facilitator).toHaveProperty("getVoucherCollections"); + expect(facilitator).toHaveProperty("flushEscrow"); }); it("should use default facilitator URL when no config provided", async () => { @@ -915,4 +916,129 @@ describe("useDeferredFacilitator", () => { ); }); }); + + describe("flushEscrow", () => { + const mockFlushAuthorization = { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b", + }; + + it("should flush escrow successfully", async () => { + const mockResponse = { + success: true, + transaction: "0xabcdef1234567890", + payer: buyerAddress, + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + const result = await facilitator.flushEscrow(mockFlushAuthorization, escrowAddress, 84532); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/buyers/${buyerAddress}/flush`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + flushAuthorization: mockFlushAuthorization, + escrow: escrowAddress, + chainId: 84532, + }), + }, + ); + }); + + it("should throw error for non-200 status", async () => { + mockFetch.mockResolvedValueOnce({ + status: 400, + statusText: "Bad Request", + json: () => Promise.resolve({}), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + + await expect( + facilitator.flushEscrow(mockFlushAuthorization, escrowAddress, 84532), + ).rejects.toThrow("Failed to flush escrow: Bad Request"); + }); + + it("should use fallback error message", async () => { + mockFetch.mockResolvedValueOnce({ + status: 500, + statusText: "Internal Server Error", + json: () => Promise.resolve({}), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + + await expect( + facilitator.flushEscrow(mockFlushAuthorization, escrowAddress, 84532), + ).rejects.toThrow("Failed to flush escrow: Internal Server Error"); + }); + + it("should handle failed flush response", async () => { + const mockResponse = { + success: false, + errorReason: "invalid_signature", + transaction: "", + payer: buyerAddress, + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + const result = await facilitator.flushEscrow(mockFlushAuthorization, escrowAddress, 84532); + + expect(result).toEqual(mockResponse); + expect(result.success).toBe(false); + expect(result.errorReason).toBe("invalid_signature"); + }); + + it("should use custom facilitator URL", async () => { + const mockResponse = { + success: true, + transaction: "0xabcdef1234567890", + payer: buyerAddress, + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: customFacilitatorUrl }); + const result = await facilitator.flushEscrow(mockFlushAuthorization, escrowAddress, 84532); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${customFacilitatorUrl}/deferred/buyers/${buyerAddress}/flush`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + flushAuthorization: mockFlushAuthorization, + escrow: escrowAddress, + chainId: 84532, + }), + }, + ); + }); + }); }); diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index a7c444f1c6..e882124ab6 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -2,6 +2,8 @@ import { toJsonSafe } from "../shared/json"; import { DeferredAccountDetailsResponse, DeferredErrorResponse, + DeferredEscrowFlushAuthorizationSigned, + DeferredFlushWithAuthorizationResponse, DeferredVoucherCollectionsResponse, DeferredVoucherResponse, DeferredVouchersResponse, @@ -298,9 +300,13 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { escrow: string, chainId: number, ): Promise { - const response = await fetch( - `${facilitator.url}/deferred/accounts?buyer=${buyer}&seller=${seller}&asset=${asset}&escrow=${escrow}&chainId=${chainId}`, - ); + const response = await fetch(`${facilitator.url}/deferred/buyers/${buyer}/account`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ seller, asset, escrow, chainId }), + }); const responseJson = (await response.json()) as | DeferredAccountDetailsResponse | DeferredErrorResponse; @@ -310,6 +316,40 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { return responseJson; } + /** + * Flushes an escrow account using a flush authorization signature + * + * @param flushAuthorization - The signed flush authorization + * @param escrow - The escrow address + * @param chainId - The chain ID + * + * @returns The flush result + */ + async function flushEscrow( + flushAuthorization: DeferredEscrowFlushAuthorizationSigned, + escrow: string, + chainId: number, + ): Promise { + const response = await fetch( + `${facilitator.url}/deferred/buyers/${flushAuthorization.buyer}/flush`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ flushAuthorization, escrow, chainId }), + }, + ); + const responseJson = (await response.json()) as DeferredFlushWithAuthorizationResponse; + + if (response.status !== 200) { + const errorMessage = `Failed to flush escrow: ${response.statusText}`; + throw new Error(errorMessage); + } + + return responseJson; + } + return { getVoucher, getVouchers, @@ -320,5 +360,6 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { settleVoucher, getVoucherCollections, getEscrowAccountDetails, + flushEscrow, }; } From f5e5d0e07aa0c6d554d66ac20a3580e2f2dc1bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 15 Oct 2025 12:51:22 -0300 Subject: [PATCH 101/116] feat(deferred): support flushing all escrow accounts at once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../schemes/deferred/evm/facilitator.test.ts | 150 ++++++++++++++++++ .../src/schemes/deferred/evm/facilitator.ts | 15 +- .../x402/src/schemes/deferred/evm/sign.ts | 30 +++- .../x402/src/types/shared/evm/typedData.ts | 6 + .../x402/src/types/verify/schemes/deferred.ts | 4 +- 5 files changed, 194 insertions(+), 11 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts index 05f5b2121b..dd2e101eca 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts @@ -1323,4 +1323,154 @@ describe("facilitator - flushWithAuthorization", () => { payer: buyerAddress, }); }); + + it("should call flushAllWithAuthorization when seller is undefined", async () => { + const mockFlushAllAuthorization = { + buyer: buyerAddress, + seller: undefined, + asset: undefined, + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" as `0x${string}`, + }; + + const result = await flushWithAuthorization( + mockWallet, + mockFlushAllAuthorization, + escrowAddress as `0x${string}`, + ); + + expect(result).toEqual({ + success: true, + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + + // Should have called writeContract once (flushAllWithAuthorization) + expect(mockWallet.writeContract).toHaveBeenCalledTimes(1); + + // Verify flushAllWithAuthorization call + const flushCall = vi.mocked(mockWallet.writeContract).mock.calls[0][0]; + expect(flushCall).toMatchObject({ + address: escrowAddress, + functionName: "flushAllWithAuthorization", + }); + + // Verify the args structure (no seller/asset in args) + expect(flushCall.args?.[0]).toMatchObject({ + buyer: buyerAddress, + nonce: mockFlushAllAuthorization.nonce, + }); + expect((flushCall.args?.[0] as { expiry: bigint }).expiry).toBe( + BigInt(mockFlushAllAuthorization.expiry), + ); + expect(flushCall.args?.[1]).toBe(mockFlushAllAuthorization.signature); + // Ensure seller and asset are NOT in the args + expect(flushCall.args?.[0]).not.toHaveProperty("seller"); + expect(flushCall.args?.[0]).not.toHaveProperty("asset"); + }); + + it("should call flushAllWithAuthorization when asset is undefined", async () => { + const mockFlushAllAuthorization = { + buyer: buyerAddress, + seller: sellerAddress, + asset: undefined, + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" as `0x${string}`, + }; + + const result = await flushWithAuthorization( + mockWallet, + mockFlushAllAuthorization, + escrowAddress as `0x${string}`, + ); + + expect(result).toEqual({ + success: true, + transaction: "0x1234567890abcdef", + payer: buyerAddress, + }); + + // Should have called writeContract once (flushAllWithAuthorization) + expect(mockWallet.writeContract).toHaveBeenCalledTimes(1); + + // Verify flushAllWithAuthorization call + const flushCall = vi.mocked(mockWallet.writeContract).mock.calls[0][0]; + expect(flushCall).toMatchObject({ + address: escrowAddress, + functionName: "flushAllWithAuthorization", + }); + + // Verify the args structure (no seller/asset in args) + expect(flushCall.args?.[0]).toMatchObject({ + buyer: buyerAddress, + nonce: mockFlushAllAuthorization.nonce, + }); + expect((flushCall.args?.[0] as { expiry: bigint }).expiry).toBe( + BigInt(mockFlushAllAuthorization.expiry), + ); + expect(flushCall.args?.[1]).toBe(mockFlushAllAuthorization.signature); + }); + + it("should handle flushAllWithAuthorization verification failure", async () => { + const mockFlushAllAuthorization = { + buyer: buyerAddress, + seller: undefined, + asset: undefined, + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" as `0x${string}`, + }; + + vi.mocked(verifyModule.verifyFlushAuthorization).mockResolvedValue({ + isValid: false, + invalidReason: "invalid_deferred_evm_payload_flush_authorization_signature", + }); + + const result = await flushWithAuthorization( + mockWallet, + mockFlushAllAuthorization, + escrowAddress as `0x${string}`, + ); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_deferred_evm_payload_flush_authorization_signature", + transaction: "", + payer: buyerAddress, + }); + + expect(mockWallet.writeContract).not.toHaveBeenCalled(); + }); + + it("should handle flushAllWithAuthorization transaction revert", async () => { + const mockFlushAllAuthorization = { + buyer: buyerAddress, + seller: undefined, + asset: undefined, + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" as `0x${string}`, + }; + + vi.mocked(mockWallet.writeContract).mockRejectedValueOnce(new Error("Flush all failed")); + + const result = await flushWithAuthorization( + mockWallet, + mockFlushAllAuthorization, + escrowAddress as `0x${string}`, + ); + + expect(result).toEqual({ + success: false, + errorReason: "invalid_transaction_reverted", + transaction: "", + payer: buyerAddress, + }); + }); }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 521797e787..ddd889f4e3 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -547,17 +547,26 @@ export async function flushWithAuthorization { const { buyer, seller, asset, nonce, expiry } = flushAuthorization; + const flushAll = seller == undefined || asset == undefined; + const primaryType = flushAll ? flushAllAuthorizationPrimaryType : flushAuthorizationPrimaryType; const data = { types: typedDataTypes, - primaryType: flushAuthorizationPrimaryType, + primaryType: primaryType, domain: { name: "DeferredPaymentEscrow", version: "1", @@ -317,8 +322,12 @@ export async function signFlushAuthorization Date: Wed, 15 Oct 2025 13:45:31 -0300 Subject: [PATCH 102/116] docs: update deferred facilitator spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../scheme_deferred_evm_facilitator.md | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md index 2181a27c31..f750244346 100644 --- a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md +++ b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md @@ -338,3 +338,100 @@ Retrieves settlement history for a voucher. } } ``` + +### GET /buyers/:buyer/account + +Retrieves the escrow account details for a specific buyer, including balance information for a particular seller and asset. + +**Request Body:** +```json +{ + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532 +} +``` + +**Response (200 OK):** +```json +{ + "balance": "10000000", + "thawingBalance": "2000000", + "availableBalance": "8000000", + "thawingUntil": 1740759400, + "outstandingVouchers": [ + { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "nonce": 3, + "valueAggregate": "6000000" + } + ] +} +``` + +**Response (400 Bad Request):** +```json +{ + "error": "Invalid parameters" +} +``` + +### POST /buyers/:buyer/flush + +Flushes an escrow account using a signed flush authorization. This operation allows a buyer to authorize the facilitator to help them recover escrowed funds by: +1. Withdrawing any funds that have completed their thawing period +2. Initiating thawing for any remaining balance + +The flush authorization can be either: +- **Specific flush**: When `seller` and `asset` are provided, flushes only that specific account +- **Flush all**: When `seller` or `asset` are undefined, flushes all escrow accounts for the buyer + +**Request Body:** +```json +{ + "flushAuthorization": { + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "nonce": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": 1740759400, + "signature": "0xbfdc3d0a..." + }, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532 +} +``` + +**Request Body (Flush All - seller/asset undefined):** +```json +{ + "flushAuthorization": { + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "nonce": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": 1740759400, + "signature": "0xbfdc3d0a..." + }, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532 +} +``` + +**Response (200 OK):** +```json +{ + "success": true, + "transaction": "0xabc123...", + "payer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C" +} +``` + +**Response (400 Bad Request):** +```json +{ + "success": false, + "errorReason": "invalid_deferred_evm_payload_flush_authorization_signature", + "transaction": "", + "payer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C" +} +``` From f28cb26320657b28ad213f01de5b357d422bbf08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 15 Oct 2025 15:34:28 -0300 Subject: [PATCH 103/116] refactor(deferred): refactor deposit with auth verification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../schemes/deferred/evm/facilitator.test.ts | 26 ++- .../src/schemes/deferred/evm/facilitator.ts | 54 ++++- .../src/schemes/deferred/evm/verify.test.ts | 156 ++++++++++--- .../x402/src/schemes/deferred/evm/verify.ts | 208 +++++++++--------- 4 files changed, 298 insertions(+), 146 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts index dd2e101eca..c25e43d038 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts @@ -20,8 +20,9 @@ vi.mock("./verify", () => ({ verifyVoucherContinuity: vi.fn(), verifyVoucherSignatureWrapper: vi.fn(), verifyVoucherAvailability: vi.fn(), - verifyOnchainState: vi.fn(), - verifyDepositAuthorization: vi.fn(), + verifyVoucherOnchainState: vi.fn(), + verifyDepositAuthorizationSignatureAndContinuity: vi.fn(), + verifyDepositAuthorizationOnchainState: vi.fn(), verifyFlushAuthorization: vi.fn(), })); @@ -119,7 +120,7 @@ describe("facilitator - verify", () => { vi.mocked(verifyModule.verifyVoucherContinuity).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherSignatureWrapper).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); - vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherOnchainState).mockResolvedValue({ isValid: true }); }); afterEach(() => { @@ -230,7 +231,7 @@ describe("facilitator - verify", () => { }); it("should return invalid response when onchain state verification fails", async () => { - vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ + vi.mocked(verifyModule.verifyVoucherOnchainState).mockResolvedValue({ isValid: false, invalidReason: "insufficient_funds", payer: buyerAddress, @@ -310,7 +311,7 @@ describe("facilitator - settle", () => { vi.mocked(verifyModule.verifyPaymentRequirements).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherContinuity).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherSignatureWrapper).mockResolvedValue({ isValid: true }); - vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherOnchainState).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); // Mock successful voucher store settlement @@ -412,7 +413,7 @@ describe("facilitator - settleVoucher", () => { // Mock successful verification by default vi.mocked(verifyModule.verifyVoucherSignatureWrapper).mockResolvedValue({ isValid: true }); - vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherOnchainState).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); // Mock successful voucher store settlement @@ -503,7 +504,7 @@ describe("facilitator - settleVoucher", () => { }); it("should return error when onchain state verification fails", async () => { - vi.mocked(verifyModule.verifyOnchainState).mockResolvedValue({ + vi.mocked(verifyModule.verifyVoucherOnchainState).mockResolvedValue({ isValid: false, invalidReason: "insufficient_funds", }); @@ -649,7 +650,14 @@ describe("facilitator - depositWithAuthorization", () => { vi.clearAllMocks(); // Mock successful verification by default - vi.mocked(verifyModule.verifyDepositAuthorization).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyDepositAuthorizationSignatureAndContinuity).mockResolvedValue({ + isValid: true, + }); + + // Mock successful onchain state verification by default + vi.mocked(verifyModule.verifyDepositAuthorizationOnchainState).mockResolvedValue({ + isValid: true, + }); // Create a proper mock wallet with all required properties mockWallet = { @@ -754,7 +762,7 @@ describe("facilitator - depositWithAuthorization", () => { }); it("should return error when deposit authorization verification fails", async () => { - vi.mocked(verifyModule.verifyDepositAuthorization).mockResolvedValue({ + vi.mocked(verifyModule.verifyDepositAuthorizationSignatureAndContinuity).mockResolvedValue({ isValid: false, invalidReason: "invalid_deferred_evm_payload_permit_signature", }); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index ddd889f4e3..817e55f217 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -34,11 +34,12 @@ import { usdcABI } from "../../../types/shared/evm/erc20PermitABI"; import { verifyPaymentRequirements, verifyVoucherSignatureWrapper, - verifyOnchainState, + verifyVoucherOnchainState, verifyVoucherContinuity, verifyVoucherAvailability, - verifyDepositAuthorization, + verifyDepositAuthorizationSignatureAndContinuity, verifyFlushAuthorization, + verifyDepositAuthorizationOnchainState, } from "./verify"; import { VoucherStore } from "./store"; @@ -107,8 +108,31 @@ export async function verify< } } + // Verify deposit authorization signature and continuity + if (paymentPayload.payload.depositAuthorization) { + const depositAuthorizationResult = await verifyDepositAuthorizationSignatureAndContinuity( + paymentPayload.payload.voucher, + paymentPayload.payload.depositAuthorization, + ); + if (!depositAuthorizationResult.isValid) { + return depositAuthorizationResult; + } + } + + // Verify the onchain state allows the deposit authorization to be executed + if (paymentPayload.payload.depositAuthorization) { + const depositAuthorizationOnchainResult = await verifyDepositAuthorizationOnchainState( + client, + paymentPayload.payload.voucher, + paymentPayload.payload.depositAuthorization, + ); + if (!depositAuthorizationOnchainResult.isValid) { + return depositAuthorizationOnchainResult; + } + } + // Verify the onchain state allows the payment to be settled - const onchainResult = await verifyOnchainState( + const onchainResult = await verifyVoucherOnchainState( client, paymentPayload.payload.voucher, paymentPayload.payload.depositAuthorization, @@ -244,7 +268,7 @@ export async function settleVoucher { // Verify the deposit authorization - const valid = await verifyDepositAuthorization(wallet, voucher, depositAuthorization); + const valid = await verifyDepositAuthorizationSignatureAndContinuity( + voucher, + depositAuthorization, + ); if (!valid.isValid) { return { success: false, @@ -354,6 +381,23 @@ export async function depositWithAuthorization { thawingAmount: BigInt(0), thawEndTime: BigInt(0), }); - const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); + const result = await verifyVoucherOnchainState(mockClient, mockPaymentPayload.payload.voucher); expect(result).toEqual({ isValid: true }); }); it("should return error if client network mismatch", async () => { mockClient.chain.id = 1; - const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); + const result = await verifyVoucherOnchainState(mockClient, mockPaymentPayload.payload.voucher); expect(result).toEqual({ isValid: false, invalidReason: "invalid_client_network", @@ -1178,7 +1179,7 @@ describe("verifyOnchainState", () => { it("should return error if outstanding amount check fails", async () => { vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); - const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); + const result = await verifyVoucherOnchainState(mockClient, mockPaymentPayload.payload.voucher); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_contract_call_failed_outstanding_amount", @@ -1190,7 +1191,7 @@ describe("verifyOnchainState", () => { vi.mocked(mockClient.readContract) .mockResolvedValueOnce([BigInt(1_000_000)]) .mockRejectedValueOnce(new Error("Contract call failed")); - const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); + const result = await verifyVoucherOnchainState(mockClient, mockPaymentPayload.payload.voucher); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_contract_call_failed_account", @@ -1209,7 +1210,7 @@ describe("verifyOnchainState", () => { thawEndTime: BigInt(0), }); - const result = await verifyOnchainState(mockClient, mockPaymentPayload.payload.voucher); + const result = await verifyVoucherOnchainState(mockClient, mockPaymentPayload.payload.voucher); expect(result).toEqual({ isValid: false, invalidReason: "insufficient_funds", @@ -1218,7 +1219,7 @@ describe("verifyOnchainState", () => { }); }); -describe("verifyDepositAuthorization", () => { +describe("verifyDepositAuthorizationSignatureAndContinuity", () => { const mockVoucher = { id: voucherId, buyer: buyerAddress, @@ -1271,16 +1272,10 @@ describe("verifyDepositAuthorization", () => { }, }; - let mockClient: ConnectedClient; - beforeEach(() => { vi.clearAllMocks(); vi.useFakeTimers(); vi.setSystemTime(new Date(mockVoucher.timestamp * 1000 + 100000)); // 100 seconds after voucher timestamp - mockClient = { - chain: { id: 84532 }, - readContract: vi.fn(), - } as unknown as ConnectedClient; }); afterEach(() => { @@ -1289,12 +1284,7 @@ describe("verifyDepositAuthorization", () => { }); it("should return valid if deposit authorization is valid with permit", async () => { - vi.mocked(mockClient.readContract) - .mockResolvedValueOnce(BigInt(0)) // permit nonce - .mockResolvedValueOnce(false); // deposit authorization nonce not used - - const result = await verifyDepositAuthorization( - mockClient, + const result = await verifyDepositAuthorizationSignatureAndContinuity( mockVoucher, mockDepositAuthorizationWithPermit, ); @@ -1302,12 +1292,7 @@ describe("verifyDepositAuthorization", () => { }); it("should return valid if deposit authorization is valid without permit", async () => { - vi.mocked(mockClient.readContract) - .mockResolvedValueOnce(BigInt(2000000)) // allowance (sufficient) - .mockResolvedValueOnce(false); // deposit authorization nonce not used - - const result = await verifyDepositAuthorization( - mockClient, + const result = await verifyDepositAuthorizationSignatureAndContinuity( mockVoucher, mockDepositAuthorizationWithoutPermit, ); @@ -1324,7 +1309,10 @@ describe("verifyDepositAuthorization", () => { }, }; - const result = await verifyDepositAuthorization(mockClient, mockVoucher, invalidPermit); + const result = await verifyDepositAuthorizationSignatureAndContinuity( + mockVoucher, + invalidPermit, + ); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_payload_permit_signature", @@ -1342,18 +1330,118 @@ describe("verifyDepositAuthorization", () => { }, }; - const result = await verifyDepositAuthorization(mockClient, mockVoucher, invalidDepositAuth); + const result = await verifyDepositAuthorizationSignatureAndContinuity( + mockVoucher, + invalidDepositAuth, + ); expect(result).toEqual({ isValid: false, invalidReason: "invalid_deferred_evm_payload_deposit_authorization_signature", payer: buyerAddress, }); }); +}); + +describe("verifyDepositAuthorizationOnchainState", () => { + const mockVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days + }; + + const mockDepositAuthorizationWithPermit = { + permit: { + owner: buyerAddress, + spender: escrowAddress, + value: "1000000", + nonce: "0", + deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, + domain: { + name: "USD Coin", + version: "2", + }, + signature: + "0x1ed1158f8c70dc6393f8c9a379bf4569eb13a0ae6f060465418cbb9acbf5fb536eda5bdb7a6a28317329df0b9aec501fdf15f02f04b60ac536b90da3ce6f3efb1c" as `0x${string}`, + }, + depositAuthorization: { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "1000000", + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" as `0x${string}`, + }, + }; + + const mockDepositAuthorizationWithoutPermit = { + depositAuthorization: { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "1000000", + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" as `0x${string}`, + }, + }; + + let mockClient: ConnectedClient; + + beforeEach(() => { + vi.clearAllMocks(); + vi.useFakeTimers(); + vi.setSystemTime(new Date(mockVoucher.timestamp * 1000 + 100000)); // 100 seconds after voucher timestamp + mockClient = { + chain: { id: 84532 }, + readContract: vi.fn(), + } as unknown as ConnectedClient; + }); + + afterEach(() => { + vi.useRealTimers(); + vi.resetAllMocks(); + }); + + it("should return valid if deposit authorization is valid with permit", async () => { + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce(BigInt(0)) // permit nonce + .mockResolvedValueOnce(false); // deposit authorization nonce not used + + const result = await verifyDepositAuthorizationOnchainState( + mockClient, + mockVoucher, + mockDepositAuthorizationWithPermit, + ); + expect(result).toEqual({ isValid: true }); + }); + + it("should return valid if deposit authorization is valid without permit", async () => { + vi.mocked(mockClient.readContract) + .mockResolvedValueOnce(BigInt(2000000)) // allowance (sufficient) + .mockResolvedValueOnce(false); // deposit authorization nonce not used + + const result = await verifyDepositAuthorizationOnchainState( + mockClient, + mockVoucher, + mockDepositAuthorizationWithoutPermit, + ); + expect(result).toEqual({ isValid: true }); + }); it("should return error if allowance is insufficient when no permit", async () => { vi.mocked(mockClient.readContract).mockResolvedValueOnce(BigInt(500000)); // allowance too low - const result = await verifyDepositAuthorization( + const result = await verifyDepositAuthorizationOnchainState( mockClient, mockVoucher, mockDepositAuthorizationWithoutPermit, @@ -1368,7 +1456,7 @@ describe("verifyDepositAuthorization", () => { it("should return error if allowance check fails when no permit", async () => { vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); - const result = await verifyDepositAuthorization( + const result = await verifyDepositAuthorizationOnchainState( mockClient, mockVoucher, mockDepositAuthorizationWithoutPermit, @@ -1383,7 +1471,7 @@ describe("verifyDepositAuthorization", () => { it("should return error if permit nonce is invalid", async () => { vi.mocked(mockClient.readContract).mockResolvedValueOnce(BigInt(5)); // Different nonce - const result = await verifyDepositAuthorization( + const result = await verifyDepositAuthorizationOnchainState( mockClient, mockVoucher, mockDepositAuthorizationWithPermit, @@ -1398,7 +1486,7 @@ describe("verifyDepositAuthorization", () => { it("should return error if permit nonce check fails", async () => { vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); - const result = await verifyDepositAuthorization( + const result = await verifyDepositAuthorizationOnchainState( mockClient, mockVoucher, mockDepositAuthorizationWithPermit, @@ -1415,7 +1503,7 @@ describe("verifyDepositAuthorization", () => { .mockResolvedValueOnce(BigInt(0)) // permit nonce ok .mockResolvedValueOnce(true); // deposit authorization nonce already used - const result = await verifyDepositAuthorization( + const result = await verifyDepositAuthorizationOnchainState( mockClient, mockVoucher, mockDepositAuthorizationWithPermit, @@ -1432,7 +1520,7 @@ describe("verifyDepositAuthorization", () => { .mockResolvedValueOnce(BigInt(0)) // permit nonce ok .mockRejectedValueOnce(new Error("Contract call failed")); - const result = await verifyDepositAuthorization( + const result = await verifyDepositAuthorizationOnchainState( mockClient, mockVoucher, mockDepositAuthorizationWithPermit, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index 33ca248794..aba7550634 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -374,10 +374,10 @@ export function verifyVoucherDuplicate( * * @param client - The client to use for the onchain state verification * @param voucher - The voucher to verify - * @param depositAuthorization - The deposit authorization to verify + * @param depositAuthorization - An already verified deposit authorization, used to consider additional balance to the buyer's account * @returns Verification result */ -export async function verifyOnchainState< +export async function verifyVoucherOnchainState< transport extends Transport, chain extends Chain, account extends Account | undefined, @@ -395,20 +395,11 @@ export async function verifyOnchainState< }; } - // If a deposit authorization is provided and valid we consider it as additional balance in the escrow deposit - let authorizationBalance = 0n; - if (depositAuthorization) { - // Verify the deposit authorization is valid for the voucher asset and chain id - const depositAuthorizationResult = await verifyDepositAuthorization( - client, - voucher, - depositAuthorization, - ); - if (!depositAuthorizationResult.isValid) { - return depositAuthorizationResult; - } - authorizationBalance = BigInt(depositAuthorization.depositAuthorization.amount); - } + // If a deposit authorization is provided we consider it as additional balance in the escrow deposit + // Note that we do not verify the validity of the deposit authorization here + let authorizationBalance = depositAuthorization + ? BigInt(depositAuthorization.depositAuthorization.amount) + : 0n; // Verify buyer has sufficient asset balance in the escrow contract // buyer has to cover the outstanding amount @@ -478,14 +469,19 @@ export async function verifyOnchainState< } /** - * Verifies a deposit authorization is valid. Checks the signature of the permit and the deposit authorization. + * Verifies the onchain state allows a deposit authorization to be executed. + * + * - ✅ (on-chain) Verifies escrow can pull from the buyer's account based on their allowance (or permit) + * - ✅ (on-chain) If there is a permit, it verifies permit nonce is valid + * - ✅ (on-chain) Verifies deposit authorization nonce has not been used + * - ⌛ TODO: Simulate the transaction to ensure it will succeed * * @param client - The client to use for the onchain state verification - * @param voucher - The voucher that the deposit authorization is escrowing for + * @param voucher - The voucher to verify * @param depositAuthorization - The deposit authorization to verify * @returns Verification result */ -export async function verifyDepositAuthorization< +export async function verifyDepositAuthorizationOnchainState< transport extends Transport, chain extends Chain, account extends Account | undefined, @@ -493,6 +489,101 @@ export async function verifyDepositAuthorization< client: ConnectedClient, voucher: DeferredEvmPayloadVoucher, depositAuthorization: DeferredEscrowDepositAuthorization, +): Promise { + // Verify escrow can pull from the buyer's account based on their allowance (or permit) + // Consider current allowance if there is no permit + let allowance = 0n; + if (!depositAuthorization.permit) { + try { + allowance = await client.readContract({ + address: voucher.asset as Address, + abi: usdcABI, + functionName: "allowance", + args: [voucher.buyer as Address, voucher.escrow as Address], + }); + } catch { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_contract_call_failed_allowance", + payer: voucher.buyer, + }; + } + } else { + allowance = BigInt(depositAuthorization.permit.value); + } + + if (BigInt(depositAuthorization.depositAuthorization.amount) > allowance) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_insufficient_allowance", + payer: depositAuthorization.depositAuthorization.buyer, + }; + } + + // Verify permit nonce + if (depositAuthorization.permit) { + try { + const permitNonce = await client.readContract({ + address: voucher.asset as Address, + abi: usdcABI, + functionName: "nonces", + args: [voucher.buyer as Address], + }); + if (permitNonce !== BigInt(depositAuthorization.permit.nonce)) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_permit_nonce_invalid", + payer: voucher.buyer, + }; + } + } catch { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_contract_call_failed_nonces", + payer: voucher.buyer, + }; + } + } + + // Verify deposit authorization nonce + try { + const nonceUsed = await client.readContract({ + address: voucher.escrow as Address, + abi: deferredEscrowABI, + functionName: "isDepositAuthorizationNonceUsed", + args: [voucher.buyer as Address, depositAuthorization.depositAuthorization.nonce as Hex], + }); + if (nonceUsed) { + return { + isValid: false, + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_nonce_invalid", + payer: voucher.buyer, + }; + } + } catch { + return { + isValid: false, + invalidReason: + "invalid_deferred_evm_contract_call_failed_is_deposit_authorization_nonce_used", + payer: voucher.buyer, + }; + } + + return { + isValid: true, + }; +} + +/** + * Verifies a deposit authorization is valid. Checks the signature of the permit and the deposit authorization. + * + * @param voucher - The voucher that the deposit authorization is escrowing for + * @param depositAuthorization - The deposit authorization to verify + * @returns Verification result + */ +export async function verifyDepositAuthorizationSignatureAndContinuity( + voucher: DeferredEvmPayloadVoucher, + depositAuthorization: DeferredEscrowDepositAuthorization, ): Promise { const { permit, depositAuthorization: depositAuthorizationInner } = depositAuthorization; @@ -571,85 +662,6 @@ export async function verifyDepositAuthorization< } } - // Verify escrow can pull from the buyer's account based on their allowance (or permit) - // Consider current allowance if there is no permit - let allowance = 0n; - if (!permit) { - try { - allowance = await client.readContract({ - address: voucher.asset as Address, - abi: usdcABI, - functionName: "allowance", - args: [voucher.buyer as Address, voucher.escrow as Address], - }); - } catch { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_allowance", - payer: voucher.buyer, - }; - } - } else { - allowance = BigInt(permit.value); - } - - if (BigInt(depositAuthorizationInner.amount) > allowance) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_deposit_authorization_insufficient_allowance", - payer: depositAuthorizationInner.buyer, - }; - } - - // Verify permit nonce - if (permit) { - try { - const permitNonce = await client.readContract({ - address: voucher.asset as Address, - abi: usdcABI, - functionName: "nonces", - args: [voucher.buyer as Address], - }); - if (permitNonce !== BigInt(permit.nonce)) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_permit_nonce_invalid", - payer: voucher.buyer, - }; - } - } catch { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_nonces", - payer: voucher.buyer, - }; - } - } - - // Verify deposit authorization nonce - try { - const nonceUsed = await client.readContract({ - address: voucher.escrow as Address, - abi: deferredEscrowABI, - functionName: "isDepositAuthorizationNonceUsed", - args: [voucher.buyer as Address, depositAuthorizationInner.nonce as Hex], - }); - if (nonceUsed) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_deposit_authorization_nonce_invalid", - payer: voucher.buyer, - }; - } - } catch { - return { - isValid: false, - invalidReason: - "invalid_deferred_evm_contract_call_failed_is_deposit_authorization_nonce_used", - payer: voucher.buyer, - }; - } - return { isValid: true, }; From 12ca3c338850f4eae033a35578d23176a2bf6746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 15 Oct 2025 15:49:35 -0300 Subject: [PATCH 104/116] chore(deferred): make reverification skippable for settleVoucher and deposithWithAuth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/facilitator.ts | 142 +++++++++--------- 1 file changed, 74 insertions(+), 68 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 817e55f217..0bca10a1ad 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -171,7 +171,6 @@ export async function settle( const { voucherStore } = DeferredSchemeContextSchema.parse(schemeContext.deferred); // re-verify to ensure the payment is still valid - // TODO: there is some verification duplication as some of the verification steps are repeated later when calling settleVoucher const valid = await verify(wallet, paymentPayload, paymentRequirements, schemeContext); if (!valid.isValid) { return { @@ -188,6 +187,7 @@ export async function settle( wallet, paymentPayload.payload.voucher, paymentPayload.payload.depositAuthorization, + false, // Skip reverification - already verified in verify() call above ); if (!depositAuthorizationResponse.success) { return { @@ -208,6 +208,7 @@ export async function settle( voucher, signature, voucherStore, + false, // Skip reverification - already verified in verify() call above depositAuthorization, ); @@ -221,14 +222,11 @@ export async function settle( * Executes the voucher settlement transaction. The facilitator can invoke this function directly to settle a * voucher in a deferred manner, outside of the x402 handshake. * - * NOTE: Because of its deferred nature, payment requirements are not available when settling in deferred manner - * which means some of the verification steps cannot be repeated before settlement. However, as long as the voucher - * has a matching signature and the on chain verification is successful the voucher should be safe to settle. - * * @param wallet - The facilitator wallet that will submit the transaction * @param voucher - The voucher to settle * @param signature - The signature of the voucher * @param voucherStore - The voucher store to use for verification + * @param reverify - Rerun the verification steps for the voucher * @param depositAuthorization - A deposit authorization to use for verification purposes * @returns A PaymentExecutionResponse containing the transaction status and hash */ @@ -237,45 +235,49 @@ export async function settleVoucher { - // Verify the voucher signature - const signatureResult = await verifyVoucherSignatureWrapper(voucher, signature); - if (!signatureResult.isValid) { - return { - success: false, - errorReason: signatureResult.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", - transaction: "", - payer: voucher.buyer, - }; - } + if (reverify) { + // Verify the voucher signature + const signatureResult = await verifyVoucherSignatureWrapper(voucher, signature); + if (!signatureResult.isValid) { + return { + success: false, + errorReason: + signatureResult.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", + transaction: "", + payer: voucher.buyer, + }; + } - // Verify the voucher exists in the store - const storeResult = await verifyVoucherAvailability( - voucher, - signature, - voucher.id, - voucher.nonce, - voucherStore, - ); - if (!storeResult.isValid) { - return { - success: false, - errorReason: storeResult.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", - transaction: "", - payer: voucher.buyer, - }; - } + // Verify the voucher exists in the store + const storeResult = await verifyVoucherAvailability( + voucher, + signature, + voucher.id, + voucher.nonce, + voucherStore, + ); + if (!storeResult.isValid) { + return { + success: false, + errorReason: storeResult.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", + transaction: "", + payer: voucher.buyer, + }; + } - // Verify the onchain state allows the payment to be settled - const valid = await verifyVoucherOnchainState(wallet, voucher, depositAuthorization); - if (!valid.isValid) { - return { - success: false, - errorReason: valid.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", - transaction: "", - payer: voucher.buyer, - }; + // Verify the onchain state allows the payment to be settled + const valid = await verifyVoucherOnchainState(wallet, voucher, depositAuthorization); + if (!valid.isValid) { + return { + success: false, + errorReason: valid.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", + transaction: "", + payer: voucher.buyer, + }; + } } let tx = ""; @@ -360,42 +362,46 @@ export async function settleVoucher( wallet: SignerWallet, voucher: DeferredEvmPayloadVoucher, depositAuthorization: DeferredEscrowDepositAuthorization, + reverify: boolean = true, ): Promise { - // Verify the deposit authorization - const valid = await verifyDepositAuthorizationSignatureAndContinuity( - voucher, - depositAuthorization, - ); - if (!valid.isValid) { - return { - success: false, - errorReason: valid.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", - transaction: "", - payer: depositAuthorization.depositAuthorization.buyer, - }; - } + if (reverify) { + // Verify the deposit authorization + const valid = await verifyDepositAuthorizationSignatureAndContinuity( + voucher, + depositAuthorization, + ); + if (!valid.isValid) { + return { + success: false, + errorReason: valid.invalidReason ?? "invalid_deferred_evm_payload_no_longer_valid", + transaction: "", + payer: depositAuthorization.depositAuthorization.buyer, + }; + } - // Verify the onchain state allows the deposit authorization to be executed - const depositAuthorizationOnchainResult = await verifyDepositAuthorizationOnchainState( - wallet, - voucher, - depositAuthorization, - ); - if (!depositAuthorizationOnchainResult.isValid) { - return { - success: false, - errorReason: - depositAuthorizationOnchainResult.invalidReason ?? - "invalid_deferred_evm_payload_no_longer_valid", - transaction: "", - payer: depositAuthorization.depositAuthorization.buyer, - }; + // Verify the onchain state allows the deposit authorization to be executed + const depositAuthorizationOnchainResult = await verifyDepositAuthorizationOnchainState( + wallet, + voucher, + depositAuthorization, + ); + if (!depositAuthorizationOnchainResult.isValid) { + return { + success: false, + errorReason: + depositAuthorizationOnchainResult.invalidReason ?? + "invalid_deferred_evm_payload_no_longer_valid", + transaction: "", + payer: depositAuthorization.depositAuthorization.buyer, + }; + } } const { permit, depositAuthorization: depositAuthorizationInnerWithSignature } = From 8559a9e55acdb844f8e7e5220a785e1774b58670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 15 Oct 2025 15:56:27 -0300 Subject: [PATCH 105/116] chore(deferred): dont allow settleVoucher to accept a depositAuth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../x402/src/schemes/deferred/evm/facilitator.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 0bca10a1ad..cbf005eb93 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -202,14 +202,13 @@ export async function settle( } } - const { voucher, signature, depositAuthorization } = paymentPayload.payload; + const { voucher, signature } = paymentPayload.payload; const response = await settleVoucher( wallet, voucher, signature, voucherStore, false, // Skip reverification - already verified in verify() call above - depositAuthorization, ); return { @@ -227,7 +226,6 @@ export async function settle( * @param signature - The signature of the voucher * @param voucherStore - The voucher store to use for verification * @param reverify - Rerun the verification steps for the voucher - * @param depositAuthorization - A deposit authorization to use for verification purposes * @returns A PaymentExecutionResponse containing the transaction status and hash */ export async function settleVoucher( @@ -236,7 +234,6 @@ export async function settleVoucher { if (reverify) { // Verify the voucher signature @@ -269,7 +266,7 @@ export async function settleVoucher Date: Wed, 15 Oct 2025 18:01:34 -0300 Subject: [PATCH 106/116] refactor(deferred): reduce contract reads with verification data getter contract call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/DeferredPaymentEscrow.sol | 66 +++- .../src/IDeferredPaymentEscrow.sol | 42 ++- .../src/schemes/deferred/evm/client.test.ts | 20 +- .../x402/src/schemes/deferred/evm/client.ts | 4 +- .../schemes/deferred/evm/facilitator.test.ts | 80 ++++- .../src/schemes/deferred/evm/facilitator.ts | 74 ++++- .../schemes/deferred/evm/integration.test.ts | 58 +++- .../x402/src/schemes/deferred/evm/server.ts | 4 +- .../src/schemes/deferred/evm/verify.test.ts | 306 +++++++----------- .../x402/src/schemes/deferred/evm/verify.ts | 203 +++++------- .../src/types/shared/evm/deferredEscrowABI.ts | 41 ++- .../x402/src/types/verify/schemes/deferred.ts | 6 +- .../packages/x402/src/verify/useDeferred.ts | 4 +- 13 files changed, 523 insertions(+), 385 deletions(-) diff --git a/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol b/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol index f77da3a860..3a9ca7d13b 100644 --- a/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol +++ b/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol @@ -369,29 +369,25 @@ contract DeferredPaymentEscrow is ReentrancyGuard, EIP712, IDeferredPaymentEscro } /** - * @notice Gets buyer account details for a specific buyer-seller-asset combination. - * This returns escrow account balance, ERC20 allowance and permit nonce for the given asset. - * - * It deducts outstanding amounts for the given vouchers from the escrow account balance. - * + * @notice Batch read account data including balance after deducting outstanding vouchers * @param buyer Address of the buyer * @param seller Address of the seller * @param asset ERC-20 token address * @param voucherIds Unique identifiers of the vouchers * @param valueAggregates Value aggregates of the vouchers, order must match voucherIds - * @return Balance of the escrow account - * @return Allowance of the escrow account for the given asset - * @return Permit nonce of the escrow account for the given asset + * @return balance Available balance after deducting outstanding vouchers + * @return allowance Allowance from asset contract + * @return nonce Nonce from asset contract */ - function getAccountDetails( + function getAccountData( address buyer, address seller, address asset, bytes32[] memory voucherIds, uint256[] memory valueAggregates - ) external view returns (uint256, uint256, uint256) { + ) external view returns (uint256 balance, uint256 allowance, uint256 nonce) { EscrowAccount memory account = _getMainStorage().accounts[buyer][seller][asset]; - uint256 balance = account.balance - account.thawingAmount; + balance = account.balance - account.thawingAmount; for (uint256 i = 0; i < voucherIds.length; i++) { uint256 alreadyCollected = _getMainStorage().voucherCollected[buyer][seller][asset][voucherIds[i]]; uint256 toCollect = valueAggregates[i] > alreadyCollected ? valueAggregates[i] - alreadyCollected : 0; @@ -402,10 +398,52 @@ contract DeferredPaymentEscrow is ReentrancyGuard, EIP712, IDeferredPaymentEscro break; } } - uint256 allowance = IERC20(asset).allowance(buyer, address(this)); - uint256 nonce = IERC20Permit(asset).nonces(buyer); + allowance = IERC20(asset).allowance(buyer, address(this)); + nonce = IERC20Permit(asset).nonces(buyer); + } + + /** + * @notice Batch read all data needed for x402 verification in a single call + * @param voucher The voucher to verify + * @param depositAuthNonce The deposit authorization nonce (pass bytes32(0) if not using deposit auth) + * @return voucherOutstanding Outstanding amount for the voucher + * @return voucherCollectable Collectable amount for the voucher + * @return availableBalance Available balance (balance minus thawing amount) + * @return allowance Allowance from asset contract + * @return nonce Nonce from asset contract + * @return isDepositNonceUsed Whether the deposit authorization nonce has been used + */ + function getVerificationData( + Voucher calldata voucher, + bytes32 depositAuthNonce + ) + external + view + returns ( + uint256 voucherOutstanding, + uint256 voucherCollectable, + uint256 availableBalance, + uint256 allowance, + uint256 nonce, + bool isDepositNonceUsed + ) + { + MainStorage storage $ = _getMainStorage(); + + // Get voucher amounts + uint256 alreadyCollected = $.voucherCollected[voucher.buyer][voucher.seller][voucher.asset][voucher.id]; + (voucherOutstanding, voucherCollectable) = _getOutstandingAndCollectableAmount(voucher, alreadyCollected); + + // Get available balance (balance minus thawing amount) + EscrowAccount memory account = $.accounts[voucher.buyer][voucher.seller][voucher.asset]; + availableBalance = account.balance - account.thawingAmount; + + // Get both allowance and nonce from asset contract + allowance = IERC20(voucher.asset).allowance(voucher.buyer, address(this)); + nonce = IERC20Permit(voucher.asset).nonces(voucher.buyer); - return (balance, allowance, nonce); + // Check if deposit authorization nonce is used + isDepositNonceUsed = $.usedDepositNonces[voucher.buyer][depositAuthNonce]; } /** diff --git a/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol b/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol index c29de638d6..2bb3923809 100644 --- a/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol +++ b/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol @@ -386,27 +386,49 @@ interface IDeferredPaymentEscrow { function getAccount(address buyer, address seller, address asset) external view returns (EscrowAccount memory); /** - * @notice Gets buyer account details for a specific buyer-seller-asset combination. - * This returns escrow account balance, ERC20 allowance and permit nonce for the given asset. - * - * It deducts outstanding amounts for the given vouchers from the escrow account balance. - * + * @notice Batch read account data including balance after deducting outstanding vouchers * @param buyer Address of the buyer * @param seller Address of the seller * @param asset ERC-20 token address * @param voucherIds Unique identifiers of the vouchers * @param valueAggregates Value aggregates of the vouchers, order must match voucherIds - * @return Balance of the escrow account - * @return Allowance of the escrow account for the given asset - * @return Permit nonce of the escrow account for the given asset + * @return balance Available balance after deducting outstanding vouchers + * @return allowance Allowance from asset contract + * @return nonce Nonce from asset contract */ - function getAccountDetails( + function getAccountData( address buyer, address seller, address asset, bytes32[] memory voucherIds, uint256[] memory valueAggregates - ) external view returns (uint256, uint256, uint256); + ) external view returns (uint256 balance, uint256 allowance, uint256 nonce); + + /** + * @notice Batch read all data needed for x402 verification in a single call + * @param voucher The voucher to verify + * @param depositAuthNonce The deposit authorization nonce (pass bytes32(0) if not using deposit auth) + * @return voucherOutstanding Outstanding amount for the voucher + * @return voucherCollectable Collectable amount for the voucher + * @return availableBalance Available balance (balance minus thawing amount) + * @return allowance Allowance from asset contract + * @return nonce Nonce from asset contract + * @return isDepositNonceUsed Whether the deposit authorization nonce has been used + */ + function getVerificationData( + Voucher calldata voucher, + bytes32 depositAuthNonce + ) + external + view + returns ( + uint256 voucherOutstanding, + uint256 voucherCollectable, + uint256 availableBalance, + uint256 allowance, + uint256 nonce, + bool isDepositNonceUsed + ); /** * @notice Get the amount already collected for a specific voucher diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts index eb7f35b5d9..294aa8aa19 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -715,7 +715,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -740,7 +740,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -760,7 +760,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -802,7 +802,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -829,7 +829,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -853,7 +853,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -873,7 +873,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -894,7 +894,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -930,7 +930,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -951,7 +951,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index 2e73c10f3b..ca66de6ed7 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -280,10 +280,10 @@ export async function createPaymentExtraPayload( // Ensure the deposit is actually needed // This creates a client/buyer <> facilitator interaction but it's necessary to avoid having to trust the seller - const { getEscrowAccountDetails } = useDeferredFacilitator({ + const { getAccountData } = useDeferredFacilitator({ url: extra.account.facilitator as `${string}://${string}`, }); - const accountDetails = await getEscrowAccountDetails( + const accountDetails = await getAccountData( buyer, paymentRequirements.payTo, asset, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts index c25e43d038..12ee0e37f4 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.test.ts @@ -9,7 +9,7 @@ import { settleVoucher, depositWithAuthorization, flushWithAuthorization, - getEscrowAccountDetails, + getAccountData, } from "./facilitator"; import { VoucherStore } from "./store"; import * as verifyModule from "./verify"; @@ -24,6 +24,7 @@ vi.mock("./verify", () => ({ verifyDepositAuthorizationSignatureAndContinuity: vi.fn(), verifyDepositAuthorizationOnchainState: vi.fn(), verifyFlushAuthorization: vi.fn(), + getOnchainVerificationData: vi.fn(), })); const buyer = createSigner( @@ -120,7 +121,18 @@ describe("facilitator - verify", () => { vi.mocked(verifyModule.verifyVoucherContinuity).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherSignatureWrapper).mockResolvedValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); - vi.mocked(verifyModule.verifyVoucherOnchainState).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherOnchainState).mockReturnValue({ isValid: true }); + vi.mocked(verifyModule.getOnchainVerificationData).mockResolvedValue({ + isValid: true, + data: { + voucherOutstanding: BigInt(1000000), + voucherCollectable: BigInt(1000000), + availableBalance: BigInt(1000000), + allowance: BigInt(1000000), + nonce: BigInt(0), + isDepositNonceUsed: false, + }, + }); }); afterEach(() => { @@ -311,8 +323,19 @@ describe("facilitator - settle", () => { vi.mocked(verifyModule.verifyPaymentRequirements).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherContinuity).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherSignatureWrapper).mockResolvedValue({ isValid: true }); - vi.mocked(verifyModule.verifyVoucherOnchainState).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherOnchainState).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.getOnchainVerificationData).mockResolvedValue({ + isValid: true, + data: { + voucherOutstanding: BigInt(1000000), + voucherCollectable: BigInt(1000000), + availableBalance: BigInt(1000000), + allowance: BigInt(1000000), + nonce: BigInt(0), + isDepositNonceUsed: false, + }, + }); // Mock successful voucher store settlement vi.mocked(mockVoucherStore.settleVoucher).mockResolvedValue({ success: true }); @@ -413,8 +436,19 @@ describe("facilitator - settleVoucher", () => { // Mock successful verification by default vi.mocked(verifyModule.verifyVoucherSignatureWrapper).mockResolvedValue({ isValid: true }); - vi.mocked(verifyModule.verifyVoucherOnchainState).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.verifyVoucherOnchainState).mockReturnValue({ isValid: true }); vi.mocked(verifyModule.verifyVoucherAvailability).mockResolvedValue({ isValid: true }); + vi.mocked(verifyModule.getOnchainVerificationData).mockResolvedValue({ + isValid: true, + data: { + voucherOutstanding: BigInt(1000000), + voucherCollectable: BigInt(1000000), + availableBalance: BigInt(1000000), + allowance: BigInt(1000000), + nonce: BigInt(0), + isDepositNonceUsed: false, + }, + }); // Mock successful voucher store settlement vi.mocked(mockVoucherStore.settleVoucher).mockResolvedValue({ success: true }); @@ -504,7 +538,7 @@ describe("facilitator - settleVoucher", () => { }); it("should return error when onchain state verification fails", async () => { - vi.mocked(verifyModule.verifyVoucherOnchainState).mockResolvedValue({ + vi.mocked(verifyModule.verifyVoucherOnchainState).mockReturnValue({ isValid: false, invalidReason: "insufficient_funds", }); @@ -655,10 +689,22 @@ describe("facilitator - depositWithAuthorization", () => { }); // Mock successful onchain state verification by default - vi.mocked(verifyModule.verifyDepositAuthorizationOnchainState).mockResolvedValue({ + vi.mocked(verifyModule.verifyDepositAuthorizationOnchainState).mockReturnValue({ isValid: true, }); + vi.mocked(verifyModule.getOnchainVerificationData).mockResolvedValue({ + isValid: true, + data: { + voucherOutstanding: BigInt(1000000), + voucherCollectable: BigInt(1000000), + availableBalance: BigInt(1000000), + allowance: BigInt(1000000), + nonce: BigInt(0), + isDepositNonceUsed: false, + }, + }); + // Create a proper mock wallet with all required properties mockWallet = { account: { @@ -895,7 +941,7 @@ describe("facilitator - depositWithAuthorization", () => { }); }); -describe("facilitator - getEscrowAccountDetails", () => { +describe("facilitator - getAccountData", () => { let mockClient: ConnectedClient; let mockVoucherStore: VoucherStore; @@ -924,7 +970,7 @@ describe("facilitator - getEscrowAccountDetails", () => { BigInt(10), // nonce ]); - const result = await getEscrowAccountDetails( + const result = await getAccountData( mockClient, buyerAddress as Address, sellerAddress as Address, @@ -951,7 +997,7 @@ describe("facilitator - getEscrowAccountDetails", () => { expect(mockClient.readContract).toHaveBeenCalledWith({ address: escrowAddress, abi: expect.any(Array), - functionName: "getAccountDetails", + functionName: "getAccountData", args: [buyerAddress, sellerAddress, assetAddress, [], []], }); @@ -1001,7 +1047,7 @@ describe("facilitator - getEscrowAccountDetails", () => { BigInt(5), // nonce ]); - const result = await getEscrowAccountDetails( + const result = await getAccountData( mockClient, buyerAddress as Address, sellerAddress as Address, @@ -1014,7 +1060,7 @@ describe("facilitator - getEscrowAccountDetails", () => { expect(mockClient.readContract).toHaveBeenCalledWith({ address: escrowAddress, abi: expect.any(Array), - functionName: "getAccountDetails", + functionName: "getAccountData", args: [ buyerAddress, sellerAddress, @@ -1035,7 +1081,7 @@ describe("facilitator - getEscrowAccountDetails", () => { vi.mocked(mockVoucherStore.getVouchers).mockResolvedValue([]); vi.mocked(mockClient.readContract).mockRejectedValue(new Error("Contract call failed")); - const result = await getEscrowAccountDetails( + const result = await getAccountData( mockClient, buyerAddress as Address, sellerAddress as Address, @@ -1054,7 +1100,7 @@ describe("facilitator - getEscrowAccountDetails", () => { vi.mocked(mockVoucherStore.getVouchers).mockRejectedValue(new Error("Store error")); await expect( - getEscrowAccountDetails( + getAccountData( mockClient, buyerAddress as Address, sellerAddress as Address, @@ -1089,7 +1135,7 @@ describe("facilitator - getEscrowAccountDetails", () => { BigInt(3), // nonce ]); - const result = await getEscrowAccountDetails( + const result = await getAccountData( mockClient, buyerAddress as Address, sellerAddress as Address, @@ -1118,7 +1164,7 @@ describe("facilitator - getEscrowAccountDetails", () => { BigInt(0), // zero nonce ]); - const result = await getEscrowAccountDetails( + const result = await getAccountData( mockClient, buyerAddress as Address, sellerAddress as Address, @@ -1143,7 +1189,7 @@ describe("facilitator - getEscrowAccountDetails", () => { BigInt(999), // large nonce ]); - const result = await getEscrowAccountDetails( + const result = await getAccountData( mockClient, buyerAddress as Address, sellerAddress as Address, @@ -1173,7 +1219,7 @@ describe("facilitator - getEscrowAccountDetails", () => { BigInt(1), ]); - await getEscrowAccountDetails( + await getAccountData( mockClient, differentBuyer as Address, differentSeller as Address, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index cbf005eb93..2b41432402 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -40,6 +40,7 @@ import { verifyDepositAuthorizationSignatureAndContinuity, verifyFlushAuthorization, verifyDepositAuthorizationOnchainState, + getOnchainVerificationData, } from "./verify"; import { VoucherStore } from "./store"; @@ -119,12 +120,31 @@ export async function verify< } } + // Fetch all on-chain data in a single contract call + const onchainDataResult = await getOnchainVerificationData( + client, + paymentPayload.payload.voucher, + paymentPayload.payload.depositAuthorization?.depositAuthorization.nonce, + ); + + if (!onchainDataResult.isValid) { + return { + isValid: false, + invalidReason: + onchainDataResult.invalidReason ?? + "invalid_deferred_evm_contract_call_failed_verification_data", + payer: paymentPayload.payload.voucher.buyer, + }; + } + + const onchainData = onchainDataResult.data!; + // Verify the onchain state allows the deposit authorization to be executed if (paymentPayload.payload.depositAuthorization) { - const depositAuthorizationOnchainResult = await verifyDepositAuthorizationOnchainState( - client, + const depositAuthorizationOnchainResult = verifyDepositAuthorizationOnchainState( paymentPayload.payload.voucher, paymentPayload.payload.depositAuthorization, + onchainData, ); if (!depositAuthorizationOnchainResult.isValid) { return depositAuthorizationOnchainResult; @@ -132,10 +152,10 @@ export async function verify< } // Verify the onchain state allows the payment to be settled - const onchainResult = await verifyVoucherOnchainState( - client, + const onchainResult = verifyVoucherOnchainState( paymentPayload.payload.voucher, paymentPayload.payload.depositAuthorization, + onchainData, ); if (!onchainResult.isValid) { return onchainResult; @@ -266,7 +286,21 @@ export async function settleVoucher ({ useDeferredFacilitator: vi.fn().mockReturnValue({ - getEscrowAccountDetails: vi.fn().mockResolvedValue({ + getAccountData: vi.fn().mockResolvedValue({ balance: "10000000", assetAllowance: "1000000", assetPermitNonce: "0", @@ -551,15 +551,15 @@ describe("Deferred Payment Integration Tests", () => { }, } as DeferredPaymentRequirements; - // Mock facilitator getEscrowAccountDetails call + // Mock facilitator getAccountData call const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); - const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + const mockGetAccountData = vi.fn().mockResolvedValue({ balance: "500", // Confirm low balance assetAllowance: "0", assetPermitNonce: "0", }); (useDeferredFacilitator as ReturnType).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetAccountData, }); // * Step 2: Client automatically generates deposit authorization using createPaymentExtraPayload @@ -582,7 +582,7 @@ describe("Deferred Payment Integration Tests", () => { expect(extraPayload?.depositAuthorization).toBeDefined(); // Verify facilitator was called to check balance - expect(mockGetEscrowAccountDetails).toHaveBeenCalledWith( + expect(mockGetAccountData).toHaveBeenCalledWith( buyerAddress, sellerAddress, assetAddress, @@ -781,13 +781,13 @@ describe("Deferred Payment Integration Tests", () => { // Mock facilitator call const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); - const mockGetEscrowAccountDetails = vi.fn().mockResolvedValue({ + const mockGetAccountData = vi.fn().mockResolvedValue({ balance: "500", assetAllowance: "2000000", assetPermitNonce: "0", }); (useDeferredFacilitator as ReturnType).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getAccountData: mockGetAccountData, }); // * Step 2: Generate deposit authorization without permit @@ -919,6 +919,17 @@ describe("Deferred Payment Integration Tests", () => { */ function mockBlockchainInteractionsSettle(wallet: SignerWallet) { vi.mocked(wallet.readContract).mockImplementation(async (args: { functionName: string }) => { + if (args.functionName === "getVerificationData") { + return [ + BigInt(1_000_000), // voucherOutstanding + BigInt(1_000_000), // voucherCollectable + BigInt(10_000_000), // availableBalance + BigInt(10_000_000), // allowance + BigInt(0), // nonce + false, // isDepositNonceUsed + ]; + } + // Legacy mocks for backward compatibility if (args.functionName === "getOutstandingAndCollectableAmount") { return [BigInt(1_000_000)]; } @@ -961,6 +972,17 @@ function mockBlockchainInteractionsSettle(wallet: SignerWallet */ function mockBlockchainInteractionsVerify(wallet: SignerWallet) { vi.mocked(wallet.readContract).mockImplementation(async (args: { functionName: string }) => { + if (args.functionName === "getVerificationData") { + return [ + BigInt(1_000_000), // voucherOutstanding + BigInt(1_000_000), // voucherCollectable + BigInt(10_000_000), // availableBalance + BigInt(10_000_000), // allowance + BigInt(0), // nonce + false, // isDepositNonceUsed + ]; + } + // Legacy mocks for backward compatibility if (args.functionName === "getOutstandingAndCollectableAmount") { return [BigInt(1_000_000)]; } @@ -991,6 +1013,17 @@ function mockBlockchainInteractionsVerify(wallet: SignerWallet */ function mockBlockchainInteractionsSettleWithDepositAuth(wallet: SignerWallet) { vi.mocked(wallet.readContract).mockImplementation(async (args: { functionName: string }) => { + if (args.functionName === "getVerificationData") { + return [ + BigInt(1_000_000), // voucherOutstanding + BigInt(1_000_000), // voucherCollectable + BigInt(10_000_000), // availableBalance + BigInt(10_000_000), // allowance + BigInt(0), // nonce + false, // isDepositNonceUsed + ]; + } + // Legacy mocks for backward compatibility if (args.functionName === "getOutstandingAndCollectableAmount") { return [BigInt(1_000_000)]; } @@ -1035,6 +1068,17 @@ function mockBlockchainInteractionsSettleWithDepositAuthNoPermit( wallet: SignerWallet, ) { vi.mocked(wallet.readContract).mockImplementation(async (args: { functionName: string }) => { + if (args.functionName === "getVerificationData") { + return [ + BigInt(1_000_000), // voucherOutstanding + BigInt(1_000_000), // voucherCollectable + BigInt(10_000_000), // availableBalance + BigInt(10_000_000), // allowance + BigInt(0), // nonce + false, // isDepositNonceUsed + ]; + } + // Legacy mocks for backward compatibility if (args.functionName === "getOutstandingAndCollectableAmount") { return [BigInt(1_000_000)]; } diff --git a/typescript/packages/x402/src/schemes/deferred/evm/server.ts b/typescript/packages/x402/src/schemes/deferred/evm/server.ts index d6386b4fdc..6041195588 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/server.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/server.ts @@ -35,7 +35,7 @@ export async function getPaymentRequirementsExtra( seller: string, ) => Promise, ): Promise { - const { getEscrowAccountDetails } = useDeferredFacilitator(facilitator); + const { getAccountData } = useDeferredFacilitator(facilitator); let buyer: Address; const newVoucherExtra: PaymentRequirementsExtra = { @@ -69,7 +69,7 @@ export async function getPaymentRequirementsExtra( let assetPermitNonce = ""; let success = false; try { - const response = await getEscrowAccountDetails(buyer, seller, asset, escrow, chainId); + const response = await getAccountData(buyer, seller, asset, escrow, chainId); if (!("error" in response)) { success = true; ({ balance, assetAllowance, assetPermitNonce } = response); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts index 7cfac00b26..977d55c07c 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.test.ts @@ -17,10 +17,10 @@ import { verifyDepositAuthorizationOnchainState, verifyFlushAuthorization, } from "./verify"; -import { ConnectedClient, createSigner } from "../../../types/shared/evm/wallet"; +import { createSigner } from "../../../types/shared/evm/wallet"; import { getNetworkId } from "../../../shared"; import { VoucherStore } from "./store"; -import { Account, Chain, getAddress, Transport } from "viem"; +import { getAddress } from "viem"; import { signVoucher } from "./sign"; vi.mock("../../../shared", async (original: () => Promise>) => { @@ -1116,101 +1116,81 @@ describe("verifyVoucherDuplicate", () => { }); }); -describe("verifyOnchainState", () => { - const mockPaymentPayload: DeferredPaymentPayload = { - x402Version: 1, - scheme: DEFERRRED_SCHEME, - network: "base-sepolia", - payload: { - signature: voucherSignature, - voucher: { - id: voucherId, - buyer: buyerAddress, - seller: sellerAddress, - valueAggregate: "1000000", - asset: assetAddress, - timestamp: 1715769600, - nonce: 0, - escrow: escrowAddress, - chainId: 84532, - expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days - }, - }, +describe("verifyVoucherOnchainState", () => { + const mockVoucher = { + id: voucherId, + buyer: buyerAddress, + seller: sellerAddress, + valueAggregate: "1000000", + asset: assetAddress, + timestamp: 1715769600, + nonce: 0, + escrow: escrowAddress, + chainId: 84532, + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, // 30 days }; - let mockClient: ConnectedClient; - - beforeEach(() => { - vi.clearAllMocks(); - vi.mocked(getNetworkId).mockReturnValue(84532); - mockClient = { - chain: { id: 84532 }, - readContract: vi.fn(), - } as unknown as ConnectedClient; - }); - - afterEach(() => { - vi.resetAllMocks(); - }); - - it("should return valid if voucher is valid", async () => { - vi.mocked(mockClient.readContract) - // outstanding amount - .mockResolvedValueOnce([BigInt(1_000_000)]) - // account balance - .mockResolvedValueOnce({ - balance: BigInt(10_000_000), - thawingAmount: BigInt(0), - thawEndTime: BigInt(0), - }); - const result = await verifyVoucherOnchainState(mockClient, mockPaymentPayload.payload.voucher); + it("should return valid if voucher is valid", () => { + const onchainData = { + voucherOutstanding: BigInt(1_000_000), + voucherCollectable: BigInt(1_000_000), + availableBalance: BigInt(10_000_000), + allowance: BigInt(1_000_000), + nonce: BigInt(0), + isDepositNonceUsed: false, + }; + const result = verifyVoucherOnchainState(mockVoucher, undefined, onchainData); expect(result).toEqual({ isValid: true }); }); - it("should return error if client network mismatch", async () => { - mockClient.chain.id = 1; - const result = await verifyVoucherOnchainState(mockClient, mockPaymentPayload.payload.voucher); - expect(result).toEqual({ - isValid: false, - invalidReason: "invalid_client_network", - payer: buyerAddress, - }); - }); - - it("should return error if outstanding amount check fails", async () => { - vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); - const result = await verifyVoucherOnchainState(mockClient, mockPaymentPayload.payload.voucher); - expect(result).toEqual({ - isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_outstanding_amount", - payer: buyerAddress, - }); - }); - - it("should return error if balance check fails", async () => { - vi.mocked(mockClient.readContract) - .mockResolvedValueOnce([BigInt(1_000_000)]) - .mockRejectedValueOnce(new Error("Contract call failed")); - const result = await verifyVoucherOnchainState(mockClient, mockPaymentPayload.payload.voucher); - expect(result).toEqual({ - isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_account", - payer: buyerAddress, - }); + it("should return valid if voucher is valid with deposit authorization", () => { + const onchainData = { + voucherOutstanding: BigInt(1_000_000), + voucherCollectable: BigInt(500_000), + availableBalance: BigInt(400_000), // Not enough without deposit auth + allowance: BigInt(1_000_000), + nonce: BigInt(0), + isDepositNonceUsed: false, + }; + const depositAuthorization = { + permit: { + owner: buyerAddress, + spender: escrowAddress, + value: "1000000", + nonce: "0", + deadline: 1715769600 + 1000 * 60 * 60 * 24 * 30, + domain: { + name: "USD Coin", + version: "2", + }, + signature: + "0x1ed1158f8c70dc6393f8c9a379bf4569eb13a0ae6f060465418cbb9acbf5fb536eda5bdb7a6a28317329df0b9aec501fdf15f02f04b60ac536b90da3ce6f3efb1c" as `0x${string}`, + }, + depositAuthorization: { + buyer: buyerAddress, + seller: sellerAddress, + asset: assetAddress, + amount: "600000", // Enough to cover the outstanding + nonce: "0x0000000000000000000000000000000000000000000000000000000000000000", + expiry: 1715769600 + 1000 * 60 * 60 * 24 * 30, + signature: + "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" as `0x${string}`, + }, + }; + const result = verifyVoucherOnchainState(mockVoucher, depositAuthorization, onchainData); + expect(result).toEqual({ isValid: true }); }); - it("should return error if insufficient balance", async () => { - vi.mocked(mockClient.readContract) - // outstanding amount - .mockResolvedValueOnce([BigInt(1_000_000)]) - // account balance - .mockResolvedValueOnce({ - balance: BigInt(100_000), - thawingAmount: BigInt(0), - thawEndTime: BigInt(0), - }); - - const result = await verifyVoucherOnchainState(mockClient, mockPaymentPayload.payload.voucher); + it("should return error if insufficient balance", () => { + const onchainData = { + voucherOutstanding: BigInt(1_000_000), + voucherCollectable: BigInt(100_000), + availableBalance: BigInt(100_000), + allowance: BigInt(1_000_000), + nonce: BigInt(0), + isDepositNonceUsed: false, + }; + const result = verifyVoucherOnchainState(mockVoucher, undefined, onchainData); expect(result).toEqual({ isValid: false, invalidReason: "insufficient_funds", @@ -1395,56 +1375,56 @@ describe("verifyDepositAuthorizationOnchainState", () => { }, }; - let mockClient: ConnectedClient; - - beforeEach(() => { - vi.clearAllMocks(); - vi.useFakeTimers(); - vi.setSystemTime(new Date(mockVoucher.timestamp * 1000 + 100000)); // 100 seconds after voucher timestamp - mockClient = { - chain: { id: 84532 }, - readContract: vi.fn(), - } as unknown as ConnectedClient; - }); - - afterEach(() => { - vi.useRealTimers(); - vi.resetAllMocks(); - }); - - it("should return valid if deposit authorization is valid with permit", async () => { - vi.mocked(mockClient.readContract) - .mockResolvedValueOnce(BigInt(0)) // permit nonce - .mockResolvedValueOnce(false); // deposit authorization nonce not used + it("should return valid if deposit authorization is valid with permit", () => { + const onchainData = { + voucherOutstanding: BigInt(1_000_000), + voucherCollectable: BigInt(1_000_000), + availableBalance: BigInt(1_000_000), + allowance: BigInt(500_000), + nonce: BigInt(0), // Matches permit nonce + isDepositNonceUsed: false, + }; - const result = await verifyDepositAuthorizationOnchainState( - mockClient, + const result = verifyDepositAuthorizationOnchainState( mockVoucher, mockDepositAuthorizationWithPermit, + onchainData, ); expect(result).toEqual({ isValid: true }); }); - it("should return valid if deposit authorization is valid without permit", async () => { - vi.mocked(mockClient.readContract) - .mockResolvedValueOnce(BigInt(2000000)) // allowance (sufficient) - .mockResolvedValueOnce(false); // deposit authorization nonce not used + it("should return valid if deposit authorization is valid without permit", () => { + const onchainData = { + voucherOutstanding: BigInt(1_000_000), + voucherCollectable: BigInt(1_000_000), + availableBalance: BigInt(1_000_000), + allowance: BigInt(2_000_000), // Sufficient allowance + nonce: BigInt(0), + isDepositNonceUsed: false, + }; - const result = await verifyDepositAuthorizationOnchainState( - mockClient, + const result = verifyDepositAuthorizationOnchainState( mockVoucher, mockDepositAuthorizationWithoutPermit, + onchainData, ); expect(result).toEqual({ isValid: true }); }); - it("should return error if allowance is insufficient when no permit", async () => { - vi.mocked(mockClient.readContract).mockResolvedValueOnce(BigInt(500000)); // allowance too low + it("should return error if allowance is insufficient when no permit", () => { + const onchainData = { + voucherOutstanding: BigInt(1_000_000), + voucherCollectable: BigInt(1_000_000), + availableBalance: BigInt(1_000_000), + allowance: BigInt(500_000), // Insufficient allowance + nonce: BigInt(0), + isDepositNonceUsed: false, + }; - const result = await verifyDepositAuthorizationOnchainState( - mockClient, + const result = verifyDepositAuthorizationOnchainState( mockVoucher, mockDepositAuthorizationWithoutPermit, + onchainData, ); expect(result).toEqual({ isValid: false, @@ -1453,28 +1433,20 @@ describe("verifyDepositAuthorizationOnchainState", () => { }); }); - it("should return error if allowance check fails when no permit", async () => { - vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); - - const result = await verifyDepositAuthorizationOnchainState( - mockClient, - mockVoucher, - mockDepositAuthorizationWithoutPermit, - ); - expect(result).toEqual({ - isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_allowance", - payer: buyerAddress, - }); - }); - - it("should return error if permit nonce is invalid", async () => { - vi.mocked(mockClient.readContract).mockResolvedValueOnce(BigInt(5)); // Different nonce + it("should return error if permit nonce is invalid", () => { + const onchainData = { + voucherOutstanding: BigInt(1_000_000), + voucherCollectable: BigInt(1_000_000), + availableBalance: BigInt(1_000_000), + allowance: BigInt(500_000), + nonce: BigInt(5), // Different nonce + isDepositNonceUsed: false, + }; - const result = await verifyDepositAuthorizationOnchainState( - mockClient, + const result = verifyDepositAuthorizationOnchainState( mockVoucher, mockDepositAuthorizationWithPermit, + onchainData, ); expect(result).toEqual({ isValid: false, @@ -1483,30 +1455,20 @@ describe("verifyDepositAuthorizationOnchainState", () => { }); }); - it("should return error if permit nonce check fails", async () => { - vi.mocked(mockClient.readContract).mockRejectedValueOnce(new Error("Contract call failed")); - - const result = await verifyDepositAuthorizationOnchainState( - mockClient, - mockVoucher, - mockDepositAuthorizationWithPermit, - ); - expect(result).toEqual({ - isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_nonces", - payer: buyerAddress, - }); - }); - - it("should return error if deposit authorization nonce is already used", async () => { - vi.mocked(mockClient.readContract) - .mockResolvedValueOnce(BigInt(0)) // permit nonce ok - .mockResolvedValueOnce(true); // deposit authorization nonce already used + it("should return error if deposit authorization nonce is already used", () => { + const onchainData = { + voucherOutstanding: BigInt(1_000_000), + voucherCollectable: BigInt(1_000_000), + availableBalance: BigInt(1_000_000), + allowance: BigInt(500_000), + nonce: BigInt(0), // permit nonce ok + isDepositNonceUsed: true, // deposit authorization nonce already used + }; - const result = await verifyDepositAuthorizationOnchainState( - mockClient, + const result = verifyDepositAuthorizationOnchainState( mockVoucher, mockDepositAuthorizationWithPermit, + onchainData, ); expect(result).toEqual({ isValid: false, @@ -1514,24 +1476,6 @@ describe("verifyDepositAuthorizationOnchainState", () => { payer: buyerAddress, }); }); - - it("should return error if deposit authorization nonce check fails", async () => { - vi.mocked(mockClient.readContract) - .mockResolvedValueOnce(BigInt(0)) // permit nonce ok - .mockRejectedValueOnce(new Error("Contract call failed")); - - const result = await verifyDepositAuthorizationOnchainState( - mockClient, - mockVoucher, - mockDepositAuthorizationWithPermit, - ); - expect(result).toEqual({ - isValid: false, - invalidReason: - "invalid_deferred_evm_contract_call_failed_is_deposit_authorization_nonce_used", - payer: buyerAddress, - }); - }); }); describe("verifyFlushAuthorization", () => { diff --git a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts index aba7550634..17501b659a 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/verify.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/verify.ts @@ -18,9 +18,20 @@ import { } from "./sign"; import { ConnectedClient } from "../../../types/shared/evm/wallet"; import { deferredEscrowABI } from "../../../types/shared/evm/deferredEscrowABI"; -import { usdcABI } from "../../../types/shared/evm/erc20PermitABI"; import { VoucherStore } from "./store"; +/** + * Data returned from the getVerificationData contract call + */ +export type OnchainVerificationData = { + voucherOutstanding: bigint; + voucherCollectable: bigint; + availableBalance: bigint; + allowance: bigint; + nonce: bigint; + isDepositNonceUsed: boolean; +}; + /** * Verifies the payment payload satisfies the payment requirements. * @@ -365,50 +376,37 @@ export function verifyVoucherDuplicate( } /** - * Verifies the onchain state allows the payment to be settled. Accepts an optional deposit authorization, treating - * the associated funds as additional balance in the escrow deposit. - * - * - ✅ (on-chain) Verifies the client is connected to the chain specified in the payment requirements - * - ✅ (on-chain) Verifies buyer has sufficient asset balance - * - ⌛ TODO: Simulate the transaction to ensure it will succeed + * Fetches all on-chain verification data in a single contract call * * @param client - The client to use for the onchain state verification * @param voucher - The voucher to verify - * @param depositAuthorization - An already verified deposit authorization, used to consider additional balance to the buyer's account - * @returns Verification result + * @param depositAuthNonce - The deposit authorization nonce (or undefined to use zero bytes) + * @returns On-chain verification data or VerifyResponse with error */ -export async function verifyVoucherOnchainState< +export async function getOnchainVerificationData< transport extends Transport, chain extends Chain, account extends Account | undefined, >( client: ConnectedClient, voucher: DeferredEvmPayloadVoucher, - depositAuthorization?: DeferredEscrowDepositAuthorization, -): Promise { - // Verify the client is connected to the chain specified in the payment requirements - if (client.chain.id !== voucher.chainId) { - return { - isValid: false, - invalidReason: "invalid_client_network", - payer: voucher.buyer, - }; - } - - // If a deposit authorization is provided we consider it as additional balance in the escrow deposit - // Note that we do not verify the validity of the deposit authorization here - let authorizationBalance = depositAuthorization - ? BigInt(depositAuthorization.depositAuthorization.amount) - : 0n; - - // Verify buyer has sufficient asset balance in the escrow contract - // buyer has to cover the outstanding amount - let voucherOutstandingAmount: bigint; + depositAuthNonce?: string, +): Promise<{ data?: OnchainVerificationData } & VerifyResponse> { try { - [voucherOutstandingAmount] = await client.readContract({ + depositAuthNonce = + depositAuthNonce || "0x0000000000000000000000000000000000000000000000000000000000000000"; + + const [ + voucherOutstanding, + voucherCollectable, + availableBalance, + allowance, + permitNonce, + isDepositNonceUsed, + ] = await client.readContract({ address: voucher.escrow as Address, abi: deferredEscrowABI, - functionName: "getOutstandingAndCollectableAmount", + functionName: "getVerificationData", args: [ { id: voucher.id as Hex, @@ -422,40 +420,55 @@ export async function verifyVoucherOnchainState< chainId: BigInt(voucher.chainId), expiry: BigInt(voucher.expiry), }, + depositAuthNonce as Hex, ], }); - } catch { + return { - isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_outstanding_amount", - payer: voucher.buyer, + isValid: true, + data: { + voucherOutstanding, + voucherCollectable, + availableBalance, + allowance, + nonce: permitNonce, + isDepositNonceUsed, + }, }; - } - let buyerAccount: { - balance: bigint; - thawingAmount: bigint; - thawEndTime: bigint; - }; - try { - buyerAccount = await client.readContract({ - address: voucher.escrow as Address, - abi: deferredEscrowABI, - functionName: "getAccount", - args: [voucher.buyer as Address, voucher.seller as Address, voucher.asset as Address], - }); - } catch (error) { - console.log(error); + } catch { return { isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_account", - payer: voucher.buyer, + invalidReason: "invalid_deferred_evm_contract_call_failed_verification_data", }; } +} - if ( - buyerAccount.balance - buyerAccount.thawingAmount + authorizationBalance < - voucherOutstandingAmount - ) { +/** + * Verifies the onchain state allows the payment to be settled. Accepts an optional deposit authorization, treating + * the associated funds as additional balance in the escrow deposit. + * + * - ✅ (on-chain) Verifies the client is connected to the chain specified in the payment requirements + * - ✅ (on-chain) Verifies buyer has sufficient asset balance + * - ⌛ TODO: Simulate the transaction to ensure it will succeed + * + * @param voucher - The voucher to verify + * @param depositAuthorization - An already verified deposit authorization, used to consider additional balance to the buyer's account + * @param onchainData - Pre-fetched onchain verification data + * @returns Verification result + */ +export function verifyVoucherOnchainState( + voucher: DeferredEvmPayloadVoucher, + depositAuthorization: DeferredEscrowDepositAuthorization | undefined, + onchainData: OnchainVerificationData, +): VerifyResponse { + // If a deposit authorization is provided we consider it as additional balance in the escrow deposit + // Note that we do not verify the validity of the deposit authorization here + const authorizationBalance = depositAuthorization + ? BigInt(depositAuthorization.depositAuthorization.amount) + : 0n; + + // Verify buyer has sufficient asset balance + if (onchainData.availableBalance + authorizationBalance < onchainData.voucherOutstanding) { return { isValid: false, invalidReason: "insufficient_funds", @@ -476,41 +489,20 @@ export async function verifyVoucherOnchainState< * - ✅ (on-chain) Verifies deposit authorization nonce has not been used * - ⌛ TODO: Simulate the transaction to ensure it will succeed * - * @param client - The client to use for the onchain state verification * @param voucher - The voucher to verify * @param depositAuthorization - The deposit authorization to verify + * @param onchainData - Pre-fetched onchain verification data * @returns Verification result */ -export async function verifyDepositAuthorizationOnchainState< - transport extends Transport, - chain extends Chain, - account extends Account | undefined, ->( - client: ConnectedClient, +export function verifyDepositAuthorizationOnchainState( voucher: DeferredEvmPayloadVoucher, depositAuthorization: DeferredEscrowDepositAuthorization, -): Promise { + onchainData: OnchainVerificationData, +): VerifyResponse { // Verify escrow can pull from the buyer's account based on their allowance (or permit) - // Consider current allowance if there is no permit - let allowance = 0n; - if (!depositAuthorization.permit) { - try { - allowance = await client.readContract({ - address: voucher.asset as Address, - abi: usdcABI, - functionName: "allowance", - args: [voucher.buyer as Address, voucher.escrow as Address], - }); - } catch { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_allowance", - payer: voucher.buyer, - }; - } - } else { - allowance = BigInt(depositAuthorization.permit.value); - } + const allowance = depositAuthorization.permit + ? BigInt(depositAuthorization.permit.value) + : onchainData.allowance; if (BigInt(depositAuthorization.depositAuthorization.amount) > allowance) { return { @@ -520,51 +512,22 @@ export async function verifyDepositAuthorizationOnchainState< }; } - // Verify permit nonce + // Verify permit nonce if permit is present if (depositAuthorization.permit) { - try { - const permitNonce = await client.readContract({ - address: voucher.asset as Address, - abi: usdcABI, - functionName: "nonces", - args: [voucher.buyer as Address], - }); - if (permitNonce !== BigInt(depositAuthorization.permit.nonce)) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_permit_nonce_invalid", - payer: voucher.buyer, - }; - } - } catch { + if (onchainData.nonce !== BigInt(depositAuthorization.permit.nonce)) { return { isValid: false, - invalidReason: "invalid_deferred_evm_contract_call_failed_nonces", + invalidReason: "invalid_deferred_evm_payload_permit_nonce_invalid", payer: voucher.buyer, }; } } - // Verify deposit authorization nonce - try { - const nonceUsed = await client.readContract({ - address: voucher.escrow as Address, - abi: deferredEscrowABI, - functionName: "isDepositAuthorizationNonceUsed", - args: [voucher.buyer as Address, depositAuthorization.depositAuthorization.nonce as Hex], - }); - if (nonceUsed) { - return { - isValid: false, - invalidReason: "invalid_deferred_evm_payload_deposit_authorization_nonce_invalid", - payer: voucher.buyer, - }; - } - } catch { + // Verify deposit authorization nonce hasn't been used + if (onchainData.isDepositNonceUsed) { return { isValid: false, - invalidReason: - "invalid_deferred_evm_contract_call_failed_is_deposit_authorization_nonce_used", + invalidReason: "invalid_deferred_evm_payload_deposit_authorization_nonce_invalid", payer: voucher.buyer, }; } diff --git a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts index 44544fc9e1..0373e3a394 100644 --- a/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts +++ b/typescript/packages/x402/src/types/shared/evm/deferredEscrowABI.ts @@ -264,7 +264,7 @@ export const deferredEscrowABI = [ }, { type: "function", - name: "getAccountDetails", + name: "getAccountData", inputs: [ { name: "buyer", type: "address", internalType: "address" }, { name: "seller", type: "address", internalType: "address" }, @@ -273,9 +273,9 @@ export const deferredEscrowABI = [ { name: "valueAggregates", type: "uint256[]", internalType: "uint256[]" }, ], outputs: [ - { name: "", type: "uint256", internalType: "uint256" }, - { name: "", type: "uint256", internalType: "uint256" }, - { name: "", type: "uint256", internalType: "uint256" }, + { name: "balance", type: "uint256", internalType: "uint256" }, + { name: "allowance", type: "uint256", internalType: "uint256" }, + { name: "nonce", type: "uint256", internalType: "uint256" }, ], stateMutability: "view", }, @@ -307,6 +307,39 @@ export const deferredEscrowABI = [ ], stateMutability: "view", }, + { + type: "function", + name: "getVerificationData", + inputs: [ + { + name: "voucher", + type: "tuple", + internalType: "struct IDeferredPaymentEscrow.Voucher", + components: [ + { name: "id", type: "bytes32", internalType: "bytes32" }, + { name: "buyer", type: "address", internalType: "address" }, + { name: "seller", type: "address", internalType: "address" }, + { name: "valueAggregate", type: "uint256", internalType: "uint256" }, + { name: "asset", type: "address", internalType: "address" }, + { name: "timestamp", type: "uint64", internalType: "uint64" }, + { name: "nonce", type: "uint256", internalType: "uint256" }, + { name: "escrow", type: "address", internalType: "address" }, + { name: "chainId", type: "uint256", internalType: "uint256" }, + { name: "expiry", type: "uint64", internalType: "uint64" }, + ], + }, + { name: "depositAuthNonce", type: "bytes32", internalType: "bytes32" }, + ], + outputs: [ + { name: "voucherOutstanding", type: "uint256", internalType: "uint256" }, + { name: "voucherCollectable", type: "uint256", internalType: "uint256" }, + { name: "availableBalance", type: "uint256", internalType: "uint256" }, + { name: "allowance", type: "uint256", internalType: "uint256" }, + { name: "nonce", type: "uint256", internalType: "uint256" }, + { name: "isDepositNonceUsed", type: "bool", internalType: "bool" }, + ], + stateMutability: "view", + }, { type: "function", name: "getVoucherCollected", diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index ae595cd330..893a2d2d7f 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -25,8 +25,6 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_no_longer_valid", "invalid_deferred_evm_payload_voucher_expired", "invalid_deferred_evm_payload_timestamp_too_early", - "invalid_deferred_evm_contract_call_failed_outstanding_amount", - "invalid_deferred_evm_contract_call_failed_account", "invalid_deferred_evm_payload_voucher_non_zero_nonce", "invalid_deferred_evm_payload_voucher_id_mismatch", "invalid_deferred_evm_payload_voucher_buyer_mismatch", @@ -48,17 +46,15 @@ export const DeferredErrorReasons = [ "invalid_deferred_evm_payload_deposit_authorization_signature", "invalid_deferred_evm_payload_permit_continuity", "invalid_deferred_evm_payload_deposit_authorization_continuity", - "invalid_deferred_evm_contract_call_failed_nonces", "invalid_deferred_evm_payload_permit_nonce_invalid", "invalid_deferred_evm_payload_deposit_authorization_nonce_invalid", - "invalid_deferred_evm_contract_call_failed_is_deposit_authorization_nonce_used", "invalid_deferred_evm_payload_deposit_authorization_failed", "invalid_deferred_evm_payload_deposit_authorization_buyer_mismatch", - "invalid_deferred_evm_contract_call_failed_allowance", "invalid_deferred_evm_payload_deposit_authorization_insufficient_allowance", "invalid_deferred_evm_payload_flush_authorization_signature", "invalid_deferred_evm_payload_flush_authorization_continuity", "invalid_deferred_evm_payload_flush_authorization_failed", + "invalid_deferred_evm_contract_call_failed_verification_data", ] as const; // x402DeferredEvmPayloadVoucher diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index e882124ab6..8898de1293 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -293,7 +293,7 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { * @param chainId - The chain ID * @returns The balance of the escrow account */ - async function getEscrowAccountDetails( + async function getAccountData( buyer: string, seller: string, asset: string, @@ -359,7 +359,7 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { verifyVoucher, settleVoucher, getVoucherCollections, - getEscrowAccountDetails, + getAccountData, flushEscrow, }; } From c71d15f3650713b5d759003221fab2c8a9477c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 16 Oct 2025 10:14:03 -0300 Subject: [PATCH 107/116] test(deferred): remove dead code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/facilitator.ts | 7 +- .../schemes/deferred/evm/integration.test.ts | 74 ------------------- 2 files changed, 4 insertions(+), 77 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 2b41432402..b74c01216f 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -300,11 +300,12 @@ export async function settleVoucher false, // isDepositNonceUsed ]; } - // Legacy mocks for backward compatibility - if (args.functionName === "getOutstandingAndCollectableAmount") { - return [BigInt(1_000_000)]; - } - if (args.functionName === "getAccount") { - return { - balance: BigInt(10_000_000), - thawingAmount: BigInt(0), - thawEndTime: BigInt(0), - }; - } - if (args.functionName === "nonces") { - return BigInt(0); - } - if (args.functionName === "isDepositAuthorizationNonceUsed") { - return false; - } throw new Error(`Unmocked contract read: ${args.functionName}`); }); vi.mocked(wallet.writeContract).mockResolvedValue("0x1234567890abcdef"); @@ -982,26 +965,6 @@ function mockBlockchainInteractionsVerify(wallet: SignerWallet false, // isDepositNonceUsed ]; } - // Legacy mocks for backward compatibility - if (args.functionName === "getOutstandingAndCollectableAmount") { - return [BigInt(1_000_000)]; - } - if (args.functionName === "getAccount") { - return { - balance: BigInt(10_000_000), - thawingAmount: BigInt(0), - thawEndTime: BigInt(0), - }; - } - if (args.functionName === "nonces") { - return BigInt(0); - } - if (args.functionName === "isDepositAuthorizationNonceUsed") { - return false; - } - if (args.functionName === "allowance") { - return BigInt(10_000_000); // Sufficient allowance for deposits without permit - } throw new Error(`Unmocked contract read: ${args.functionName}`); }); } @@ -1023,23 +986,6 @@ function mockBlockchainInteractionsSettleWithDepositAuth(wallet: SignerWallet Date: Thu, 16 Oct 2025 14:47:35 -0300 Subject: [PATCH 108/116] refactor(deferred): move server functionality to x402 server code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-express/src/index.ts | 21 ++----------------- .../x402/src/schemes/deferred/evm/server.ts | 19 +++++++++++++---- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/typescript/packages/x402-express/src/index.ts b/typescript/packages/x402-express/src/index.ts index ea1c1583fd..c2d46f5802 100644 --- a/typescript/packages/x402-express/src/index.ts +++ b/typescript/packages/x402-express/src/index.ts @@ -437,21 +437,6 @@ export function deferredPaymentMiddleware( const x402Version = 1; const { verify, deferred: deferredFacilitator } = useFacilitator(facilitator); - // Default voucher store is the facilitator - const facilitatorVoucherStore = { - getAvailableVoucher: async (buyer: string, seller: string) => { - const result = await deferredFacilitator.getAvailableVoucher(buyer, seller); - if ("error" in result) { - if (result.error === "voucher_not_found") { - return null; - } - throw new Error(result.error); - } - return result; - }, - storeVoucher: deferredFacilitator.storeVoucher, - }; - // Pre-compile route patterns to regex and extract verbs const routePatterns = computeRoutePatterns(routes); @@ -501,9 +486,7 @@ export function deferredPaymentMiddleware( getAddress(asset.address), getNetworkId(network), facilitator, - voucherStore - ? voucherStore.getAvailableVoucher - : facilitatorVoucherStore.getAvailableVoucher, + voucherStore?.getAvailableVoucher, ), }, ]; @@ -583,7 +566,7 @@ export function deferredPaymentMiddleware( } else { try { // skip POST /verify and store voucher in facilitator - await facilitatorVoucherStore.storeVoucher(decodedPayment, selectedPaymentRequirements); + await deferredFacilitator.storeVoucher(decodedPayment, selectedPaymentRequirements); } catch (error) { console.error(error); res.status(402).json({ diff --git a/typescript/packages/x402/src/schemes/deferred/evm/server.ts b/typescript/packages/x402/src/schemes/deferred/evm/server.ts index 6041195588..aa50e2ba05 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/server.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/server.ts @@ -19,7 +19,7 @@ import { useDeferredFacilitator } from "../../../verify/useDeferred"; * @param asset - The asset address * @param chainId - The chain ID * @param facilitator - The facilitator URL to get escrow balance from - * @param getAvailableVoucher - A function to get the latest voucher for a given buyer and seller. + * @param getAvailableVoucherLocal - A function to get the latest voucher for a given buyer and seller. If not provided, the facilitator will be used. * @returns The extra data for the payment requirements */ export async function getPaymentRequirementsExtra( @@ -30,12 +30,22 @@ export async function getPaymentRequirementsExtra( asset: Address, chainId: number, facilitator: FacilitatorConfig, - getAvailableVoucher: ( + getAvailableVoucherLocal?: ( buyer: string, seller: string, ) => Promise, ): Promise { - const { getAccountData } = useDeferredFacilitator(facilitator); + const { getAccountData, getAvailableVoucher } = useDeferredFacilitator(facilitator); + const getAvailableVoucherFacilitator = async (buyer: string, seller: string) => { + const result = await getAvailableVoucher(buyer, seller); + if ("error" in result) { + if (result.error === "voucher_not_found") { + return null; + } + throw new Error(result.error); + } + return result; + }; let buyer: Address; const newVoucherExtra: PaymentRequirementsExtra = { @@ -85,7 +95,8 @@ export async function getPaymentRequirementsExtra( facilitator: facilitator.url, }; - const previousVoucher = await getAvailableVoucher(buyer, seller); + const getAvailableVoucherFn = getAvailableVoucherLocal ?? getAvailableVoucherFacilitator; + const previousVoucher = await getAvailableVoucherFn(buyer, seller); if (previousVoucher) { return { type: "aggregation" as const, From 4e9c1690299f5227defd3e1603a273e69ce23fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 16 Oct 2025 16:01:13 -0300 Subject: [PATCH 109/116] chore: update deferred spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- README.md | 40 ++++----- .../scheme_deferred_evm_facilitator.md | 84 +++++++++++------- static/x402-deferred-protocol-flow.png | Bin 461147 -> 481814 bytes 3 files changed, 69 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index c1be1cf3be..953b29ae77 100644 --- a/README.md +++ b/README.md @@ -98,34 +98,32 @@ The following outlines the flow of a payment using the `x402` protocol. Note tha ![](./static/x402-deferred-protocol-flow.png) -The `deferred` scheme modifies slightly the x402 protocol flow to allow for a deferred settlement to happen. The following steps outline the resource request and payment verification flow: +The `deferred` scheme modifies the x402 protocol sequencing to allow for a deferred settlement to happen. The following steps outline the resource request and payment verification flow: -1. `Client` makes an HTTP request to a `resource server` with the `X-PAYMENT-BUYER` header containing the `Client` address. +1. `Client` makes an HTTP request to a `resource server`, optionally with a `X-PAYMENT-BUYER` header containing the `Client` address. -2. `Resource server` retrieves previous voucher history for the `Client`, responds with a `402 Payment Required` status and a `Payment Required Response` JSON object in the response body. The response body contains additional information required for the `deferred` scheme encoded in the `extra` field of the payment requirements, it will contain either a new voucher id for the `Client` to generate or details for the latest voucher for the `Client/Resource server` pair if it exists. +2. `Resource server` processes the request and builds a `Payment Required Response` JSON object. The contents of the response include information in the `extra` field of the payment requirements, gathered from the facilitator: + - Voucher details: either a new voucher id for the `Client` to generate or the latest signed voucher for the `Client/Resource server` pair if it exists. + - Account balance: The `Client`'s onchain balance including outstanding vouchers to settle. Based on these values the `Client` can later opt to send a signed message to authorize deposits on their behalf. + - If no `X-PAYMENT-BUYER` is provided then the `Resource server` just responds with a new voucher id. -3. `Client` creates a `Payment Payload` based on the value of the `paymentRequirements.extra` property: - - If there is no previous `Client/Resource server` history, it will instruct the `Client` to create a new voucher as payload. - - Otherwise it will contain the latest voucher for the pair, allowing the `Client` to aggregate payments on top of it before setting it as the payload. - - Optionally, the `Client` can sign a deposit authorization to allow the `facilitator server` to escrow funds on its behalf. +3. `Resource server` responds with a `402 Payment Required` status and the `Payment Required Response` JSON object in the response body. + +4. `Client`sends an HTTP request with the `X-PAYMENT` header containing the `Payment Payload` to the resource server: + - If there is no previous `Client/Resource server` history, the `Client` will create and sign a new voucher as the payload. + - If there is a previous voucher, the `Client` aggregates payments on top of it before signing and adding it to the payload. + - Optionally, the `Client` can sign a deposit authorization to allow the `facilitator server` to escrow funds on their behalf. -4. `Client` sends the HTTP request with the `X-PAYMENT` header containing the `Payment Payload` to the resource server. The payload will include: - - the signed voucher (which can be new or an aggregation with a previous one) - - (optionally) A signed deposit authorization. Allows the `facilitator server` to escrow funds on behalf of the `Client`. These are the funds the voucher will be claimed against. +5. `Resource server` verifies the `Payment Payload` is valid by POSTing the `Payment Payload` and `Payment Requirements` to the `/verify` endpoint of a `facilitator server`. `Facilitator server` performs verification of the object based on the `scheme` and `network` of the `Payment Payload` and returns a `Verification Response`. -5. `Resource server` verifies the `Payment Payload` is valid either via local verification or by POSTing the `Payment Payload` and `Payment Requirements` to the `/verify` endpoint of a `facilitator server`. - -6. `Facilitator server` performs verification of the object based on the `scheme` and `network` of the `Payment Payload` and returns a `Verification Response`. - -7. If the `Verification Response` is valid: - - The resource server POSTs the validated voucher back to the `facilitator server` for persistent storage using the endpoint `POST /deferred/vouchers` - - The `facilitator server` will reverify the `Payment Payload` before storing the voucher, which makes the previous verification call optional (5. and 6.). +6. If the `Verification Response` is valid: + - The `resource server` POSTs the validated voucher to the `facilitator server` for persistent storage using the endpoint `/deferred/vouchers` + - The `facilitator server` re-verifies the `Payment Payload` before storing the voucher, which makes the verification call on previous step not mandatory. - If a deposit authorization is present the `facilitator server` will execute it. - - Then the resource server performs the work to fulfill the original request. - If the `Verification Response` is invalid: - - the resource server returns a `402 Payment Required` status and a `Payment Required Response` JSON object in the response body. -8. `Resource server` returns a `200 OK` response to the `Client` with the resource they requested as the body of the HTTP response, and a `X-PAYMENT-RESPONSE` header containing the total outstanding payment that is pending on-chain settlement. +7. If the `Verification Response` is valid, the resource server performs the work to fulfill the request. If the `Verification Response` is invalid, the resource server returns a `402 Payment Required` status and a `Payment Required Response` JSON object in the response body. + +8. `Resource server` returns a `200 OK` response to the `Client` with the resource they requested as the body of the HTTP response, and a `X-PAYMENT-RESPONSE` header. At this point the `Client` has "paid for" the resource access by means of a signed voucher. The `facilitator server` stores the vouchers which can be redeemed at any time. The settlement sequencing then is as follows: diff --git a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md index f750244346..07e8ea5acd 100644 --- a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md +++ b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md @@ -13,13 +13,26 @@ As for write endpoints, they do not require traditional authentication but inste ## Required APIs -### GET /vouchers/available/:buyer/:seller +### GET /buyers/:buyer -Returns the most suitable voucher for aggregation between a buyer-seller pair. +Retrieves buyer data for a specific buyer, including escrow account balance, asset allowance, permit nonce, and the latest available voucher for a particular seller and asset. + +**Request Body:** +```json +{ + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532 +} +``` **Response (200 OK):** ```json { + "balance": "10000000", + "assetAllowance": "5000000", + "assetPermitNonce": "0", "voucher": { "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", @@ -30,13 +43,27 @@ Returns the most suitable voucher for aggregation between a buyer-seller pair. "nonce": 2, "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", "chainId": 84532, - "expiry": 1740759400 - }, - "signature": "0x3a2f7e3b..." + "expiry": 1740759400, + "signature": "0x3a2f7e3b..." + } } ``` -**Response (404 Not Found):** No vouchers exist for this pair +**Response (200 OK - No voucher available):** +```json +{ + "balance": "10000000", + "assetAllowance": "5000000", + "assetPermitNonce": "0" +} +``` + +**Response (400 Bad Request):** +```json +{ + "error": "Invalid parameters" +} +``` ### POST /vouchers @@ -339,43 +366,31 @@ Retrieves settlement history for a voucher. } ``` -### GET /buyers/:buyer/account -Retrieves the escrow account details for a specific buyer, including balance information for a particular seller and asset. +### GET /vouchers/available/:buyer/:seller -**Request Body:** -```json -{ - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532 -} -``` +Returns the most suitable voucher for aggregation between a buyer-seller pair. **Response (200 OK):** ```json { - "balance": "10000000", - "thawingBalance": "2000000", - "availableBalance": "8000000", - "thawingUntil": 1740759400, - "outstandingVouchers": [ - { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "nonce": 3, - "valueAggregate": "6000000" - } - ] + "voucher": { + "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", + "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", + "valueAggregate": "5000000", + "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", + "timestamp": 1740673000, + "nonce": 2, + "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", + "chainId": 84532, + "expiry": 1740759400 + }, + "signature": "0x3a2f7e3b..." } ``` -**Response (400 Bad Request):** -```json -{ - "error": "Invalid parameters" -} -``` +**Response (404 Not Found):** No vouchers exist for this pair ### POST /buyers/:buyer/flush @@ -435,3 +450,4 @@ The flush authorization can be either: "payer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C" } ``` + diff --git a/static/x402-deferred-protocol-flow.png b/static/x402-deferred-protocol-flow.png index 03c43104beddb30eaddd361b23db79f849218868..9c04851f69e5d3ceda8cabc70369dd159f37e02f 100644 GIT binary patch literal 481814 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

OJj?J#4zV0zg29o<^c;>2 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

?zw^50 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

-G%=@UBj`Q3gHMytL%h7*a=Pa86^627 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�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

    hBi|`T40f8r+%)UO5{Xkew}%2) zTE$KbxkocFN!FgAqb48!qTD@VPEz+8X#-m$&1yc7M$Z*}E6z@=bwlZDxMeQG{Iu1f zB1OwxR0sc5-uxnyjOjSTA@cb=#uhnFWtkhZFO*TC2W2z_Hrf}WipP`7`_42t9wadn z?o|rR7fSF3G10J+BC%x&7D}~y9#rXB(2Z1GAC9(5fRFk`Bwj-F@DovUnR4Z7CPcc- z@Z`(!kCla6DCTg)z?id5_}v;T6l-Zaz3JZhrVQUpOO*yC<&~*=%>*gAZhDL2Dx0)9 z6U!A8cc>h1w6%kV*#|3s3ra-h*a}nPtbeZ%OJ zm*fpHG|TkBHtedqNy6XS3wI%f=~BX1Z`U*^sBlJ)2Y=O3#|qm$n1%!*diKw*_4X zo{1#fQ8%uv8p z-sB(o)YE*#*&<>C{=;wVT_B0{iPZ}NmLUU@Wd;aS+Y?8SFV$Soh1G9GXjUfR-PBzP zKlt;XHYGm5MY5z}wEW_V*nSU>5DA@iWaVB~%C z@*-tyBB%sjkm0)9h3lAB6;VeOBz!cPyr7{iJqpclp!8MiPRqbt#R^B&7Q2&ZwJ+t2 zQmn0J$If+~c)yn!ZyUW43n#F^9f*a$KKfJTF*c511rHYS$U1!UZw#opToPBfFIZ_` z^O=6a#$-g-**Vin@Up|p$ zyWi<(6va^KBJ=4?7PAysrFI%F9)&F$wJg!#5Z8kXoyuuH`nff^5|;%xlw z9O8`1a6dl4m76!pz0u}yZkm}>I^tsKSSg5m{{oGbVaM||LuHfBOw9SeND1xqzU&HoHMJ~=9Rmbh=;?QJ-96ZtaWtXKCeCU z-aFC!{Sf4>JLoJs_-627=Y5y9bLcr$kNs}TfjP}52^Y{mD)A5#07oj=HCEfzpa17k z52344!=T~b`i2#qGQ3JoEcpQ=T>CN81`8h9)eVTpnAS{3`MzpK+8 zH$-=Tu?A?aC4+v+^j|lBW+Gev*p2PkoYtLqA$bH;aj?8|3|cq7Z08AfZTj1x*U!uv z|Bs(I$3_Ln~75VXf_@Un(_DyK~4!9S-RS+h|qXd=iFR;$?YEEFcjmn(==b(p~RfXS)Hw=vMXOdv6YJ zTjjsKyGR>MOnxB$x5r1n#_a0k&sP0<5hyP09OPIR(A-+y#ET&NDf_=Z4@ZJgvZS}$ zzC{0j`2x{p2&ZQyE53O*8Q-@*eO{K3OKZS7@lwwIJ@(i5fZ*WX(c7~oxS~Out0Fir z(KVt8>bFFneva^-4@1A-i3T0b0T0UtZn?<0+=sJ!Yo7m(0E?Z5{8ew{S&r>Si|P_y zgWTc{Bf?*;`ppW`ON21V;a`Y%efW=hAny*Xc`Mm-t~aaxkKG0OVi3o|;0qII9O4Mi z{9$W1?~5ggKv-E``deEw%vJPo`j3Z;-4Bek^=+=7GXv-_Mx!WBS#Q?@2>z%uSi(7b zfMAsveZFhpKyR!FuWe=cKi9@~EpBTGHIhKUvT{js8+Y>K|EHb<=d=htTUz-4DZ9>q zCa<<#aTTqipr9aN5k;1W>`kj|Au4-DK}2MUY(j|C$rcfi85AKhBYP)W8M5~tQ6hUp zAR&-Jz7rM2zF*(B{pZMep685v-`91dn0u-I@5WP}fvE?|PyfE5dx$<;{^`Q4V8GZ> zIUmi;_qn zzN)u>HGV__bkR`td859oy?^=vdrr1DfcDj}_D6rw)IkQjrv3`O{i|M>ssbO~nmBMr z9k)wf>EEqa>K1S|qxU-^>BW9g z#d%!@cBx*bqqCkR8vV+cTYlMx>U+T8%RP2tm#4lh;g>&bwme`3`nKR>5tAFXf9 zc1-Gr)7p)_{WqvD6_H2!vR*0Krw7<^kS^L>nDPS<628)Eo8G7u1ZnOAD&*(F?#O!i zo4xlsjd&r;`4QT%O&~rZEWA`-8?DDgQDV8OP@XEn|J9tgZnyRRHS6l z2^Y!6-=|Kt+ImERxsTzVdumiJ!P28_B~1t_0A>1Rdb7o?LR)Ck$IZJ z3PnzU3w6)E{&(Zm*#N?2VT;j5)b_6)@Ps+v!w$xq@E!kneCkdn3(eM-d%w4Zf8L0H z@PHsqppJ$g7G7(H3%?)!x65VCJhj`UD?hI-beH_Uv3%0cfeq12lCk?{=hJV0BWBw0 z2{)AKChh&%O_^dcxt&TK_#rg>XET^#E;P9{H2(+KD*PvSpTGhc3m{1?o}e@BRY z@kt=exw0D93#zBivaI}&z5oX3zlYko!a(6X=@L2l**|Fa+5-DqTlIbazPjqELQG9} zH_Pt(kg1B>DjVAN>k|AB@P0i3AgLvM4A3$(Iv)HHYUpYGI%U(+{r^hSnhBXcC_^PC z-G}T?=Mlvj|Y2-DS&w|2fm;TfI#}NwEmBP z_uC9oe`WfeABzr4Z}L~+LhqaZ=X3#w`-uyAfEY)h`#+E`dg{{ueZ0Cg5Td*$N6C{c z;i8v6{`Vh$UV}{rDX150aB0T#@X!Atop(FxpD%anDKOu@@uEZDHdr0M>(F0#x?&MAiP6KA(*T-d49`rg5A7X0tCU zNo*2G=7;}R6~I)2L8q9xdiKO*@Z)wJq7vF8==a2sKOivv!IIe$gQ`Sx$$}0a)W7=SM6~ScHq0aVRoYhv<?hVx~bray>6`JyE8k?>y9=Zx_bDI*lggP)y{?jv09%C-GHaXg6kn! zJJx=!PONDdCCMZq;vVCE$d)U%tir!{#PCO4xeB=Jq|CvJH%7g0+uRQg13UITJQsV? zJa#;-r9iSNpcZgr;knxH0QubwDuP#Ei18GL5z^#B# z3*LT8HAsvnI?PDH))W&dLbYH&8Ldu&J*%+EI8^&P(@QUCCI_rJn1891q>{HKeXhOw zYl2hQR;DQOO^a;I&`YfSOwjQr<=@Z|sHS$N&bkpKmQCM#V~y8%=KXf9)Pq5>1n@8L z$f5#0sGI^be>!;JUBO`6t5~GF%fj`|se96i%gV2Z%|E-Cw znScwKQp`Y;`H!BTIzOwC+7*!*a}(;eELCn31&Anv%UCdl+&&9oRZc8Ao2p=f_nll< zzBZpxG+%$6Ly#)xr#qvnDLcaMbk{YGyg8W=r+raJA{RbEI)tp3Z7 zaX%B6%(IcFjI9adSLAs=zwo+gDn%))Vsybkmi_w8pc$v?iqZF14y%IytlR%`JuEvf zvMb+t&)AoQ;+NN}Co{dlu3*WWx&xNkh`B}Wk1jUlM=2|wA{ zH?+s4^c<3Hfl_3k>2iql>*X)x0;wjKyC2A*u0-a=#Zm&^f~OoNb+{BOS#IPenIG_0 zpuGY(A-&c`o3(waza~)aud|k z+CIfaa=WSVZrbdZP_Q1=@^S_n>+!|xs0e+Uh(r3UzDN5!cYDA#2vMY5A*>2nuzi*% z>n%8aYce0D_0wL0GBFpeG;CUr+5gFA>a%iBbpYp-l;h^Z2PeKNRSYQWINP)s_fql5 ztBCJsaua*T;K5g$^Z5opuWoS@dgXasJ@qTUVLI1MqzOfsbK~6Ke!aS#_~kpdQM7@| z;(w#`h304q$+F3({d~$*B#sIfPKFPu-TA@+nL4>GppBfAdu+pGC<>(l2ZL@5o`XpC z`))vqkS!NCezUP)|F1O;Qe~0=efx&5ANKP<8Q;hxc*>Cy&CC0_e8evY?fQ5HvYRfzWpq4 zb6`LBUfHaD+YfG`{-AHb6aI6xt{Z{V#*0+=`;eWO`Pz~IPg*Ato2EZ7sveI5@Q^BR z=!St07k`g=KC)K0`M{iFx+(%mBS6vb-onhkFh71{$G*&hZh9G9&otdrii1Ge_@nLz zswh`~s;iu?%{b#voLUbR_)27+s>iY*T2XUNh-I6<@#}^!4++v_lC`{)a`@uL{lMpU zbPwpffiF!vOovKfUvxmWsZwd70j*kLM+P7QoY$OK(lo;x(RX|qr6txpK@0m1DLVV! zh_|KT*wl0&$_#&s|2c`k9bQ_e0a!PbWf89A+5hU)!pL%EZS`f9Nc80Pq@bUIH22?x zcAS*5|B~ZLW!s*V0H$coOk`@vSAO@dzfK?29}g+qGEyXriFSHp2P7m)hutCQXlLpy zyz|y9?X*iZJ|$U|?BX*L7pYXo_=rfEC$94jd`R}eK~TwFzYUUK*)4nUdUosZ4&*|K zYh6%@clsqb`fcKP95g+GMtGye2WiSFc2}Jw(`Tb1<}MAYBC0hADW}uMpQIpd9E|G2FPltRF0WzM~-_~914MMENDhdK6#Zr*ZFAnUX=MJb*D(G7K{ZH#rW&n3I%cB6qE2FRu7Gf5P2NZC)58jG z%e1}M&}SoBRYscRW`5}#Io8;O#&l#K3wbfBmEtR+HYw615iOy#yfoH?K4^y^SFlaAAHQ_f6t~6?D^P;M-d0xk@w@*VORpS$f;f%A>O?yw6jQS2GZ*LjfEn(J8 zwHseVFoejVWSherZuN2~Q)`6BsC~!wNr<7of`$!YHqLj60v0X$c@bG~BF+Y`LRg;L zEm5rSaVI}q8Hoc+PKv3)%RZyreETr!SQlV`I99#p01amH{ zgcQGp+Ociu>P3?Za8+3sSnfxN`{}ByxHx^}gQyFY^Jucc;%+y|jK%0#le9P)%yBjOps@xy2N{UL`_Hy&vAiCtRu|A`lv0 zXs6~{wlFc|0U`R5_Ii5BMlK*V zhs9@MIXcbVALW75POm2< zuE!&9_8g4UH#Cs+vmtjfwxz%p#|7e@t7S}cd2T1VVTD{uM)LfEx22ctSn1*=H&bc2 zUhIwR(3Ktg4~7l8t%!kZ06m~==w)bw9UDyS)Mp%#o0i4( zw?P#t@Se8#yAV(V95eV6u7NI8x`Nu~`7K-X(iEsslA=@{FxsG?ar)YKeW!Bt)0+qU z>Ckz<3n4F}`Q!sod;PlR?H=n~OA4$Yju4uMGU2ca55WaxMyKeSqrk<wPP7l)BnQ ztXW2*&<`S0e@lI~eJt*T2!u6dA`z!uYUK_<x z&*_8>BNcw~@|VnKY8Xq8j&W2#K_411Aaq5Og?JVS9}@P~%LD>KHFUtkzy}conB)RVk)kpb?e0y^ zf9rC!YjScMU#VW@gXz`bA*GvhJmg*TBu6L9=JAIaFmy?Y&kL1^j;KINcc%KdDiGpi zgGZku_b+>K{YcQ3aH(!q-c0(&3H=%|O>P669m~X;-DngQ86Y{byt+)!8>ZIm&b+kX zbmrkL1{SJ&QBg?YO0`46l?q}T!s=p_bD~?8)Uqw3s}?4TYF8@9>&r^eZlWqXlLO$ zzGo>v#dFYHcu-VHvpL3Hnewq~ZPjOl@QGMmENc*&Q)V+b$5r{lxARKV(*?v-M-kp; z=cL`Pw^LMLObi?t^99nLW*&cdjVs643tqZwO|-tb=GFOJG#433cy}VPZ!{pgGxuy0 zD#b7Fq5VjYY2LtOFe;^iSD+*mT~>0-S2<+ zQ#2xe5?uFuR71=U#VPUO&}8^6#@Wc?e#L8~(VhIlfO3kr%Yw??H=ve>O)qO5qs`J+ z9j0I5*B@m?&pDBA*n}!55gv;!JE_$1_U1FB688?AEV8aPml=?*C{$y!p`;G>phvbk6q+$>a(!oZLNL)Oq%vy!c4y@-eDZb`8MK904D_5kZgw<4z?3EWtw)V14Moh=lR)IbB?Ze%I zt=nV;LhE3nN7~A#3Z^=zmw<4gT3ewgNM|tbn3Aw=fR;vPfLrZS$`0B>;9Pm%V3=x3 zA+lCaRK>=RN+&jpx}h$var|OA-L9ukr;ldJq07taM33juPcGU#?9}TT5l02Tz;hrf z5fxL-(V^S$Gg}eBKNe<>NE2UpbAqQE206fIK}udS?ve1VHB&Skvk_DEVN+hJk@X3M z)lPYI>!6AUPz4`)l@|12M?8((8T-gdi^-q5rCNeJV=(#7erlZL!?o-BWL?s+%LiQZ#hdy@lLgj~(eLi3+vdPwVkb&IL)$^h3 zNcW2(NLc<{OWUxfifJ0oG>l=}xe1RLgkhhmMD~)5Yd~86#{yx{4))clE{UaWDQ%cT z37X#TLFf1Zi?@5cUfObJ4J}}D_?i;xU z^BDU%tzI5|juR0*W!ar}ruINImwWQf8EEILteO}7 zHo|dMel8v8PR^!>QjfI)!7GGYIaWIOj!*cZs`nZ=xl|cb-ls*TWoA?@&CJ$HLSgva z1ecf?E}OvgDULp9dUXMf7An!z<})A!d5Ffej`@NoT2p#bcBUJ)Dx-S@$&HfUYE$n# zn+c33(Ak)heznJKr9)m=+X&GiktXexaKZOj2A*Q1QqoVZ3Po#Y?;Q}U<+v|O7j0rw zrJXDdaS~>~Ryyb&d7uwpNkBaE3APv1M*^30&A*C9RclM{!D2N+)*`PCTn}X*Wm8@9 z9i+cLc571mUGPdtBdK&W$}Pd6b)XB}Ss2@Ai2*90Vkw0-ll@GXJtqsl>+PrDrNw&W z$Fl(i4M#`y)*Acc%pz4IRTqiM4Ru!T zCL2`GjzC*Ev8hJEUitSpUmC&e6{tB(y3k$4h#>!(p|n z&Y1LR)y(4gn3A%-L3`}m&OQ1#{Y5zEygM5wjx|dC2>D=#iFFpCey;+>M|eRhiyTSK zC_Ggr?b785Wyk4Y`@L|qxF%a=_c?i!B+))teIU|%!RL!Bw>#arxZiWv3jNgCF*+tob)*RT`d zmI(?xdGzWRM>`d_>zAq0sNG)}T!?44{Q5Of#LMN2AL&I_3@jd-GCvWdM4+1PZ%xR~ zxzL?0>Q+TEP^7I!XD4>%NVPrTgkF7Pv<4O2VKS2|j@R*xx_eM`!MTSM^VM02jTR$Xjq3hRQz-Os7iv8LRUXl=ac^EZQi+qDw zsz^-Jv-wjVEnQu6L~}{ouz0l;u*I-1ns5t5l~96%VpbN+G;eteW*bGw_(+)_K9pk2EheL4&^?_|VmxxndRe*c!D#naluco(1KZJn4&wf_T;0t|I z1HT}aRzo)>k=2XlVXN-KfmZ-YXiOuZBvh_dTWAuY+YUWyDb-t4;dALgQDCxzV}V&x zWFcNUCd97PxYxp~*0#%9pZqcE0APO0Ri^%_C%nLBD`RW%Vg?-zY@Ml|yX99n8{e*3YSjI}XFNsxJvhmKDQ=K4L0v&6(YwU0tYrj=aPYq*#eQ z8T4}B=NMfb{j)riQ=g)HSsj|(@Auug{URpdHVSBfOiqxd(@Pcco6Bm1M#z3vmQeA| zB<&=*2zWU$YqqYpPApHELG)Z6pG@D~wrWl3%Qa2cK5(cooz$m2lO5PNvW7xF$*XuD z=2>GN0!44+0=B?D)+z~Y0s3=XRzbc zdNa3G>cDiBTJlrQJYC}Ta>8gO?aau{>4E7YJR2mRkg4BvjBQxT-aJ-75?_S1xiD8y zZ-CV%ONSF)X3TRX``xOTcrF#{5_NeIT-trAH|ZT30}T_O zIECvEigQRoNNW6X(bL)|+}KvqV6B7PCoz~;zF6|yCR6!SyIr|mj@BOzg7N3*AX1xz zBu4l@(Y_x(dn_-y5?v{n3~zMrNQx`t8)Ln{rYl!nRMon7*lv>ey2bPbmbN}MOf99( z$0CI%d|G55&n@rOmvBh(yjnp^>RMW>ns3~FNibMWW|EOLdCcv)zXB;|Inkz`7J4p2 zo#0KONUY3{(Tv~%iYFn3B%iDgDvYp+?kLVnITD_#c?Q_?duCHL#(%na;S z`-|v|G`2xeIwejm_ZJEJ>Q0^)zHM5Wf=y@;`>s)yei7lt)A`_8=nsu0E3qRAi23CD zl2+C*gQ(+1l@MC`eFrGKvLv6YcUXzUa!XB7gT{V=CSWvQq$!SXXT=8L49C}g6~z4we}|MVPnq2aRtuJ4tBtH86(>2f0Cdy@n5oU zUBFH+9k2^u(Plxqjg~(jyb%n&76zO0fT;Y6C1db2p*I4jKXoFkpoO@*qo#dFavbdg z$kzJSG|^ynl@Ze?ca08x%ZHD1O_efBex-&IH@|0%K<|K7P(;1*DQOrF9X9El@{2rf1rRcPS+!u6h9Ry>Bm*2njgE`o^R?O!;rxGF+PwG=!+z!lg=u01+uWniqW;aM% zWM-4y803+cB^E2gew7KR+*Zk1F~`hWPS;{LY0XR1vWYJ2JylFx`2onOq+1~k%OoLW zV2LlghjPQbL!ulxeD9*s(9DatY_~F*gk^TfO6c9efb{9{yKh(Ya8LcSG6tU_BuhBh zaENBzoi=Wjv+K`I1^+l8Y8=B1_02-JeK>Tsqur={y;ms#9CPX$ic@%|boDwlelkS< z*x|KyxVOGLT-v1(+;hn4OOovgO+e*(zU9cXIoqiGh0`4>NtRO+)qF9QNx#PoaPaCNxAHR-Nz8smbtU08k zb;N8s> ziu8ace$xaCYZG?tu@6FdA9@w_f$z7hGBDU*k)2yP31nqlK6BdRSTO|~yo0!op!g8F zXN<1TJ%7CxXBF@Il5#2>8kV_^nHjsHR6UgcU?DoNVt~zZgz!0XXdu5&L&TX3Trc$O z@WoVGsAvoE;732aulCl7-otG)cbL4l2jM;jja0tq>|`EHZJI9~P_BhT?Ja3z<|K)C zwNS5zA3xq8gv*&#PQVx>Ie&5-PvEOSkIuF6zEQKo{+KYV@;+9~nr@e#*W+7XkG%v; ze9#l{TGr5@!@K!Q2yT~XOWphts)G8ezBfll2b-=?7fd{mQg4Y}y~94m=eHprQD=Hv z)iBh&-j&Qq*|ez~bxX$KtIxMoBcL4v`Lml~aNuf%RRnAG?7Z_lYyakEzaT~SL(115 zD{_ZFBc{KuW>dYC6quW(MzWHQ$TbqeiBk%H6DnL4|9S71yv+-gKkT};E$`Tbb z1kPPHy38t{LJLJ7AVrvrv3kW|^okz~9?=oY7GqTF#u5M2Lvxa1W5%(i=bAFS`}$rg ztCWV@v>DfOKvH?z8`(>UWD|*eTBbp(m=ZQefrNVr)T=utDVZge)5)`nbaFL`7vs zLa&+2dguBrRv+gSH!-nTfH|s*lCSjO3<>a0S30nAfRC@(EUTu6I8?>DHK|11B|Lb&(O`uO+gG%E+b`d(*C0u1pMty7JQr(a&wHSwl-~a~4dk zkyk2KaE3_4x<&^*DfASN(8{5qQ&c_^;u;8rLn(34z2Y-2D(P}f1qnj62bGFmo-6QD zesekjAN)GsIon7LPH3EUJykK{g~NvUD{H(O%<@l}eCjpv9O`wP-S@5hpg@%4$9ESm z&c`mf_awE-HkDQcG*6?FGkV|-Nf^Hrt#DU9AFoa~WnSfp!eV9?imRTELm@dyGrA;& ztfB1L#hO{|Cz(a_exEuV<3TD=G>?HNGIM@AWvlD6kn2{{rq!U>vooYe#>6J?WoeEl z$!cUR#aSU^G1tc%=FbAO)HQWN0}-BsV_G=$;SP{L zjL#xmydmrTw$WLtbbW-Ld)VP*#Aq+w((|d~{b}H?#k(d<5J)8$hit^O197V4(t&yf z&r<1gEWRX(^CLGcm!YvQ1J8IX$Cp#?!u@bE0jr;EPcAapM9AJ6b~{A@cLi^`J$cn> zuM4lo?+e+MDX84pXZC8d;Sv|z$OpqEM3_+i?gzIoey+I(r7&*_Gc1VMXbc5-MHQwy zo*J<&BmTw`airWq2N0$`Il=v&q1xBcO`N%a;Z~F$@f~_vgD3Tx9WP!v%Q)2De&sD- z8tYBDoCv(WOapZni`+G`eOI~2o<+e@-`_2oF43h6uNXJ9#?S{XHN|>{Ecq%6);sE3 zSX+8nIeMs?&(D(lwPx;|aA63K_25HmaE-oMaWSa2y0!Zz@oc#TJfMEjKYZh`^2>Rb z7+%*(Dn?f(7t?u5qqv87Uere4%El*ocIu?*W!pD4Bu4Le zU|c(RW70r6;*jL?DV3MW%UsEd<_!hCY7!6jx&%g^JL5&FGU>~P$OZT=n`IB}^t#NK z#*o}eNRDNOz?{eP2p|!xY7K%_M`rG)lK1AhL{?ilx<@liEydrOZiFAZY#fu9lufaC zc-C0SsL!rBUq#oF(9qu-ovt*A7OEd$L|9Y1I~`Fe0^%#l3Z1DsJ62fl!B7VIv%?|k zwBPI8R+N-$$>*Gz<)Mr_E5iy|UZ!Jl1}0|L8a!VwD5W>GDdb)YVEBJrOdu^-#TS8; zA&J97G%#7g&4lXSIg__lu`{zrr4r>1DpC@AJqOfWwLt+!cd^>Hhtz_ww=L!*yY}FU ztKm3fIDgkDL+#`rGj+ON!^zcXSA{T;w7{x)6F zb_#?=mnZM_=9+4I%59fzH?|7|UF%r825AyM<7VNWzece(ztZ7`(ly649BsU{yDj>8 zw{DEjJO-g+v8}ZChA7jd1#L}?uFB#dTC7kjW*QvCOO1ts)^DbHb(L7sUXBzjaEq2I zpR1gWF43m(;uh_w0=rvr3zC%{cBEB-D4|xI&00@e$w>p~Jim@!?S0OeD^NML_=?&L zTT%rm)Ak)30GymgS}6AvjL$5ua7qrjt&$MgBD?~1{y>-@H8u%GOAB3QqjT8z|lb3ZDV^1!~k==icU_|PS@i2xiyT5!0 z3rLs4MN4MrPKT~#C&2=mRt-YfaThO&;4JfCZqf0Q4_>SUI*Jm^c1pOnU7$;k_SLToT!Q>E zKbu9pGlMr(3zDD9Dve23C0Kd9xX1Zaf=wtTjJ|5v_JYbEn4@hJNub2`>5<5NWn`7L zXG?J@WrW5ZSJ(3K>D3IxzM;xWBb=S*3Z|m6{>-!b(6*wJi-)<=m&&=CMrqA1-5xR& zcM!Eqg7B=g&=zsT;@qW(+9}zxzbR zo1#%!AGzEHypybm_QIYSAzB`0X$jA3DVULw&j7*yBIqrUFYy|#1t~7K;kv9?-{(X< zG$y4qM{A13VIvoSoyc0d6(AAy#A4cG+)EB+Nhm`VB!IM;zi?ARw1Ms0k9UMZHEc#< zSW>>`k|)W~b;!TdTTo$g=Z!^Bu7DO@ceKe390O&Zz~QQA51e`?!)HbE&?~xDNYHmt zyDd^A<)`uvMW+{USLphR3}STWyeUIm#kVPDjYC9qC)RP!utjt>ziN4Or(IN>jH&sr z&eATN8E`#W?n848%DzlO8(SCN7eL<1rUCe^ zfD3~!(!c(8uCUeWh(O92TCWmAyw}p?#7Ay7zntFQW5M2`{BX4vxi+h{3GE#rLPsV= z?Vz?{7n7N75W5j%rHk{I4&#_HnZomM)a8;Rz9d6QOIIhS>XZp|u4HUU_2cVF4ED43 z_UDTLnV6$Rz`8z64un`}1P8*Cd<~a>E8AMHpTySX#zJt!rw|yaj16iVwLR1&Mwc0wEy&m^ z_jnwbjp^hdTXWokS|5(H*V!&o$`1N=6yN+Q(C)VdwsCGMm~D;Ow^qJ1^HfW`5BrvX zNItMifDuq#trbTlqLSL_QuXFMX+K4%VMP-Gsi+IeT%9KJ9?g zz8U84WWPobzbK9LSv;6Y3C@n$!>oB0jZxGLm}O<|jyl5_QMjdLUIFclhKJy4)$#(h z*561o;z*38c=_NX&$S-8bB5>`4KAxx`98xoWu(FSa(S(P`qG#vIz3#LszGUJLnLQ$ zXkcaVL}B)GX;499e!nr{i{iS1k_7maWG!Gz=W(l)!X3~N>0zz#vs02t{KecYDL3l0 zOjGGKZWKKK9yW0-xGVnys3+=jS@|0qg)U(ss`^y=%Bn5A=U}Y(%*EiE1T)QYP}{sD zsG(7PX#vA{=FKr|YIQABw=WKG`*Od2F%tCeFYV^DyL<_eV!)*Q%FRmjmlN)#DD)XLsT#{DfZmXKH zR@Z&8MKA2w5xe6l*LksK`$#1qv+eXdF8Yp;Q{W%of+M9eb=tS{oM9_#aUwklaf&P2Br>FL+O^+TpRSx930kmX7XUNX|l#*S9-Zqw8_# zDXZ?;^v(`K_F}l)`tLxsZ1tmN0L;;x&4E~`CCUOT?w;@YV! zt)F}7!%ut~-YtOw)jtUd;7|sl?jvS-$(;1;=s!a1IAfUkj_bifc$ZJnE?trcc@;?N z$c+ahhJqYiycU^amEB{t9AGEqLkH2<@}7xKkRo5aq**Y$&9)RGzr(;Y&GM?46ONBMS5d2tr>d#s3<2L9K-0 zoT2CSboPABGZ5#&%gH@<9Ulr>XG9~reDHhv4x_}m1zNXy*18K@ArE-T z4~jlq!)iy>JaKdOA0RSho&8iGB;Njg-|VlXT`cM9|jBIRtZB58=ov64~eIwcM)orJx@FrK>=lKpP(acn@=ioE0W!vyUQt6frk%OyWj1LO;1@_>C&M6W z%K@Ye)+`*zlCF`jj30HU9qgrETpuZ}|4l314x)N&{>)08y?|d)r$kDx@<>sak;(En zIO-r>JzkOM1{soulk4Cg%=O8NiOz*~H)eIpIuB%ziW5gkK(Sw3el6Z9h_#&9b$kB8|Su zfnaviqIb*x8f3%%P$=I9h{@VOueIH{^g!xwe$~}+>0D4j4V*4g`_#i1kGtA1r)#5K zMCV<^3&r$=Xx@x5$Fh#k{l-Gc-X`l$s;T_`(g{liT@od_v*>aQ8$vU<2?dg9;H;=+ zkJP>td^O%Kkbwfpa-mX_5@ze1BZ%g6a#k9b`i5MRIV~<@#;g|44XPnw7gNk&U1|i8 zLHx8kY>pTT^lqZt5axDMTm6A?IJ>+64){OnnSEr`H0ce zDRFckT)w=k)z+vmo<4O!iF*Gz%*W@u)5Q_QJ1@O0&Ee_eofF2aV^NoRC&N6n{ShV7q z-f>LnId^^zdYp}Ilt8&$uVpNM4%TEQo0|6~dXH{Be+g9bMOok}&@Zu6Ljo;HJYy+N znYEQ+U4ro@xzJKu2~C#zrI?$kQ@+J@t%z~*`g0NV1fME`QcEa_T7 z2LA+?Xs*$T_!s4bCx+)obt8KdQ+#LQX^xrsUh_RB5gHE~LFzm)Fuw;3E58G-_RJ<|i3#X{9}?rCmX;yd>y$yZF;x2L+}TjY$Y&x3?G zWtKluPszE^&)CUB=JDfW(<@Kx*z}|3hN_N_&rT+L+p4b5th{VfTs|+%o@r{c4$Du7 z3*wNA6z3L!Ai@P(-P)uaq`k6eSMhs7)-7pMR2kNfwfFO5#F{#p1sh(!_bD=va*+Af zU}@R@xi5ES7qeAD@L`?TKKCBy>lOp9v-*Z4ju=Z= ze&Swp8jl%i)M=g)9uaMzs3W%2SpWfmyvG5EO2&c=>si0ajJQ{kHHlax{6+}*cSFNP zx63^+g~z@jdt8hJ7H29#+p=^#T?b?)=0GFt`7THw?P??X{@xa3#Su6byO1Eve&+e8 z&GbyUNPW^H^3^cH6a3yLbbRBYt-|H!gN(V#)|u=V+P(bBz6JeBablqk!{a?P`|y}J zNF{9v1@4`Cyyv>AL97>iU8KHnuHyB9X#Ip(v&*g0Js(><`blX6(dzV{&!3qVOy)k{ zL`BXJ5+a73JSVPZ=azwsi5_Dou%8M+!oH+@7IYKDo&r_7&WrlE*{xZsa-vE#4kVzV z<)WTiIcAGZCOYJKF2)O)n$)i?gzwp!y?`>155UqYb1BQplp22k9SJ7QT&hM`YDOD$ zDzoK|DAg>U$fTTdotKxqKh-w~w>{+fkt(vn4-K|+8Sq3KPnWK-B{F6-(sTXe?cp$7 z@f4^M6&k3P^uRD>WQCiN$%eE`W;Mnt3oFW^bdf&Bljuk)!{Y?v#p11HTpZGX1 zLubY~3CHVqxh48e zHaT3fc2ViZ8lKWeDW2nND7o4IXVu>Ng)&)a9WvZi zJX5IdFzXA+^~$`;t2rZ*eqnOZK${e8I3-x?06zHRP(KRvMkr4x>!#;QH4((~ue;C9 z)Zj`Y_Cq>GeeV=^8FM8?ol=`D3gENF5XvaeJr^>CUK}6Pxfx=|6r+0=1%GAW|4>7f zX?jz8N`%=T*rhzLF}#t6XgX7$Q~0r=pKbJ(y&?f3G|@-NHMMyJ-72|0vu&&qvsg4I zf9;9yCAaiy|HC?_AX(`Y+#%_sHhg`=)2Hjmi0450v;7@_3Xeh}N8R-muM(_50pvW?<0-Qt zT`l?3(1E@;XiLEly`Ikb%w!n<^JqfDjCGf?M{5dH3Nq|v9ik96E1=4jrKItEw5^op zzFvNd+1~Ifa@(gFRrA<%-oO%#EME;Isn;sKLT_e<)^nsrw~}S6P|EeBd0c|)Owm+8 zAxg($K-R!v&o=J!M={G|h1F@tF>2Xo!w9X77~bl>m!kmIqFoUNil+w>6)|213mHU#7@@% ztU=-sZUT9A{Jt*(VK_vSYH_4!YliTTYnE zp1427L3ld@7bS_!R)h3wAy!Q2u)KSMOP%BL&BUi&r4C5R7OB}V;U-0f%47Z-JvLT( zXT*VrZ7r*q@V2Sdg|N2a)=^}wD$BsuF>cXYztr;~A}kHDo_4A@>n4kUcG&?8IWg&UN<%e1)AHZGXs8cmB4z zC4gQGJ?{7xIs!Ks&wA(^7wk_#JGh?WExR&~Pavhl%U@eL);VUle!Bh(lh9X1@cpZ8 zKYMBemHgnT=U1rs=WDm?T-85ZwhwVh6)4#IdxTVY9R<^17hU_KxY`|eJm;~uK9P0njzN6)g z&I9TUNLBNB)STh1zA$9VvQJhHKb?M%{6 z9zf>sxw+Th^7Yz}(d>UcE~!mmaOHUit&I~BG|G8Xb>lBzKIQL@%b#^jxhV5+*pQ3Q zKc8~hGWi`7`FFC}o&lCn){)!g&f;cD0p>RSCkXp5d_$iZ07y!5nqWoKSPy-t_6d5- zdez*d;31QhCCGK(|55hVaZPvcAF!mTASm9_B_b-_T?VM2sFb6X7%)P*OB4)B5Rg_< zsY!PzNVCx+2Z-cgqiZmpGrjfeegD3{-}5~G?6ueSiF2-Voh#l~oX5|D=|G>1hcqJh zD2FWq`JKbunUJ8OU%W;+c9+_A=jNFoMxsgs<4^7ilq9zBxoP%y=Z|hH(&oRz(;LJ) zNF0!SazFlaQRVFLk#cR$rS|>WU8NlBDO4hu9s>#+&$f!D+J(vc|L#2amW~7uA`$g~ z$QXC~P-61L-|Fz^z+Jnusy0yqj^q7dzmmCvkw1-+4^ME(6 zGw7TN{spZPacRU>iB_jq&{kJgB8~(GGps-)>n@f2FrI%sz?T<15Vw?ES%2(#-0$&& zFFf>CyW}}h&v;o$jp#pty8PO6lX4&Q-X>=RQq-t1d#q6>9|`;})_EOhlB-mV=YKI1 z#|cpV-V!b30*0|6Me?8ZcZnc&lc6tPZJfL~?yRl$v%H^;{y8q?Vvk%$vkxx-p!tt& zKtZdR^%T(m<_*D?3mhTFti`EVoz^s83^Eb*iOq3-3|(2BpaUIfaf(34{}Lew zx0P#t5FmgQGPoav=7$xiT_nDfTP=L!TF#Ms#M^=6om20eX6#$U4{QhpJM(+aQNuKRa1{Xf4#j? z3%zV&bV1+z>t?T)(jH{QGP|}nQot`hmY8d5*E(yBAE&)hj&^il1~vPQ=}WGyJ)Rn; zP{f*ssp(V7hi5DHnnzz^JYOxlVOB=ZXeBv_Ur%uw~@IT5j@p zyu4=#R>?}6tDB0ndFWDLONx&y&9G0kOVf+&3=o#69q^q172_`32eg?+TXOt%6~o9r zSE-2#H z-O{PRx9M+lFN(M;I7Rt6b-Pb^*H@$vi)DgeR!J2ENw>fpYIGQVSEkfxEc!W);)xNv zSxgKHJs&~-=z=g&9Z&Q0g0>3(I*Ux7p|z;YzdO;QYqTh@l3lI6h+osCO|*j_oGnIO z6si)tS*sGubTw8YSj8t!`&O()j16J@KB%}ehd9@tP0TxeF;h9V)VB)?SuX>d;OI5b zPs;mJ2Y)fR^+)fi!D`A?i1sB&tWM4@RI9KzEy|+nK;O3LR)8|uiJEOf$lt|Ns2<@o z2YHblPyn|)FKD#LU}j*S%#jr{c<88K_z@J!X)UwQg^Vt}-3}u_jUL~u_O)B`3|vi~ zs!&R~*NK8}$y)i0+X;OPz`V<#=i>*hEDV7g5kW8aw`l8DApyNIh$=cz76{B)juo(Y z3c*PhUBFk$wJc(OXA~~-=F<{lDSUFb01P>WB zjOYV=JSHzGoqTTl0oMs$})L zP}v>-gK5Ww#S@1~gf)D6U!eC=(jdflCgA}T6swo4txe=wW3Vv*TvROeXac9nr#zbP ze)x6k6!)mVtW(duOe8soj#Wu-KR=~#xUuxj{IV-gHw)_X`DkhlVtq=2>umg*Xh-?c z18%EdSb$|7Ul2QM=v8{oyN>`T@T3^N|D%CMQUDrEe7-_Cc7V_ga^K`%XYNr!B(ntm zSjHbM#2_uy`uIE6!@9KvcLEw113?on?dCd5$gHAWo=R+3VQUeg?u5?t`pI^!Zp>+P0M+Li!E`7^S;LY#2nBR;)wc zAs3r|=UqL~2%vY0wZQh-T+0I^*CYi}PV6%1T9(@qYmr~Bvwi8h5gj?zcT!~i#;v-% z8rB+=AQ5)|kQZK@WL5_0~ofe>dgO)#zaD03KRVOC}lZ$YHzo>Z%-S?AAIZhM2Aho`Mqqb$st`_n21a9Odw zdGzzNM5d*;jJ2?iHQRYsK+g;m zdCB~hbyQw?si>(k>b?=sFILPVPUe0?s{Tx}whx#UeLTvaiGZ{RHrc`Xp7cJwt07qr z+^j;}WL>v?sO?0FCvwU`mlAJJNpL~KVOtn@wL^g!KfP?0v?}yg5}X|#k7yFEs{^X> z*0_SEBch_fY?v)mF5<807t^kDb9aGXITju(9N~Lm!p5`pVeT=0z@!RbNigOW!74p@qx!3l=HugCL*zXP(IkEr52-&mN%3LK3CYg)bp1=dFM*&R?rC_zHaCYxvJ zdqq!iXC>XGJ$^2eSh~H3b%JGQ>T*P#g*euh3=6rnjUH~dW#^}STNkR+AV%tl0ScS4 zRHxZp>-q`y)Hu*qqk72gR-eq4!qU(N7SD0U4h1R)(L#HN3vh-r%SQRv9*tS(O+*qa zYD@Z=Cp6Xbs_qd>#DV4{K!~+-eIU^XjeXDIx77AXo*24BOFfeQ{&r%n<$=!tO`pwG zNhIFTuPaRA*a#eC1`s}*vBuKO^+Y)fI%3k}d z#*wXslvS$7J}UUaS5VJkTj?u%kW`;ZEN_?d&fY-dIkKV;ee6dZ;X&(_FJNwkI+Cq( z3gLyw_bpk6^4nLcTPi@U(@T#6P<1a(%%pLMGfGAdzr-9$r#3S7*&k(njjh@K>=rRF z5ax(}`$}4qu}Px1$FjcFPLb727=2Z9UZM|utjdY4#N}YE1K#Tyx3A>wP72i;KKgjy zzgh8|`njT~QD^Kf!+FlZu3fp6b|yyKjceE;} z*IH*}&m*Ha+1X=#v#lKdgv=0)qIr$oJ)c47gv7vNBB}_z%~rkj*QSi`tVWct{0T(U z*S3+{2Hyi)suQ5&Jl7(AyO*N z0Of9S>c*AP*oTak0Ywi#Nm5f&laVzxGzbd|gRk7eWd0_i!4G#vJ0;1}j2ndaC%A(j zUL$xjn|)_>rg^#{F^N;LV+^kEvb}mFkm~eB3@5CHSgkC_ZY%ZX)mlAXTpM7y7Pp+bRMx>D=&Plh zH*P*B;W*j-usCIKb1Z9AtH`I?p}ybRtzKTvCuwPDv(oBQdg&pp65APtI!YItPdPf+ zN&-06eVM@jpz6MO1@YmiY!;>Fp5kDV_}KFyMk8VMrRTT|GKNyaM%iNhC_6pP?3V47ATG5U;p;Y%)&g2k zWL$ZeN#ZUh6 z4O%-vFW+!RB^~h{<5c9JbH^Ct;i~<Il8IQ z=Pc!n#>~>npFG@4grr6YpL&-Ve@=PQG3%4_-CykalSjQM7(LC8F$O<8v~V*I3+>?y zI6_MGG$G*ON;198+*88SvVez=kx#dn(%h-8)hXXnwPKVnzW?pI5&606lQ~Xt)xl|> zp|a~U?;Go@+O-mTCfn@~LU^hZDJxtT6z-z&k3(|p_vzbWwqx6(cwUu1f?Ghe?xKoG zXztn_v_`w#O__6p8VBh}bdNx01@fl{CuJQ*^F(Q4?KivW*Y3s{7c|Jjs-5$TtM8=Z z6N+17?qGHwOSmc0w=#-tczFcY%&jWhrG6K5=<)!~~9`b@#Ecs4bY|e_%`b$$R|mmn#ZV#j`?d)p3KBhlTcQ zsEI?5{Onlk%8**g#d}ta*3~D)hdf5NlG*bwSUOa$jx=cmd_)JSzMONNs?4QqmJ4c8 zC^y(OEsHTma`_{3MKf=;etmXazwz~ykjCpul6~pxK_NK*l0;Cxzuhp!mCpN;^3to+ zL+gMVMAK6C@kAgij5%i}-mJ>4@;;(qWF!g=unfOHKAsh(ZajHKlGmtq z_?NDTGVBn=O=W2&svt3>^F ziq~eJ#EV+4h~2MuqY)@$pt+;qI~$rTNvN2 zoLlKfvFBb0^2MCV)-$cCntR(GSF%Fc`RP@uBS&Gn&bEK`jbFY9sd-C{o47iAn}s+1 z=;mw8W!+Db@i2vga?W1UB--^Oii%Mzjlt#RFA@EVW3{8xY@N=|uDg6okJwUE_>6P~ zk}i!D)QSW=EqAoRYbx!%>kL&oB=c6{(Q&BzY=4u?0cGchLcq>R>fKpbz4nE_^4STa z^T@6Fb0;h{A_W`--?-}vzIi6b+iK+A-l4C}lN*08k|tlY+45VbMoU>bo}&->2X-k~uzsu_crXVpR$>n>G>bOlH4QVqJ^ zo%WY%t9XB4j(sE2i~p$B1yi&0c3XI>K|7Y{YUze#8p_rCXls1bD?)K>i@n%x+ZgTq z*;YLwG6l(1yB)l-Y^i9l5uc0t$gY)oQ^xswcg8M%LcLWbSORvNzWbJ%tk#OTn;;Q& z>J}_|_i7kJcD?Of{!>L3iN~Yu82$PnFE`I7`4CMvTcMebn1M%U$?2%T@qE)qB0oF< z>}Z~JMD5BCsqs^Eh*D5%ST(v-xb)N1H5OYvTsjl16chN;-ktgG3m)WClNieq^Bv-ve zG+~6Kopu+)EW6_+*lB!N2jSIB+6GnHj@EaxvqIT=HJJzUEp$#L2f78R(S4viX^cB% zn2V3&GthTwOPnM1KK%AoP$XzT{6YU^e*KJ3fB|JY@|OeiBuodHo_`>56bfUz(3L12 zS(K?BADG81oUM|N*qY^ku+-^w+eE+Qc}=Bha7kTm;h6rWg{!rH@Iz|(Wh>LXRKd%Id9MZ?qiQ?aBI@ zENZuO7gGP-qH?Z4?pn|#q00}Hj~i(#Up98loIm(RopiWWeSjGE&BBc9UNufuG~O5+ z_}~;R{?Ww1IB_?PFTfDmbFh@Fpg4MCA$Var_-4I*a+h~LB)uwad+IsVyDEXGi1^@4 znjQV<#*x^19!6B4qS}Qp*7J+r)1{~zqq<$+mt#(t_bk1L;)CAt578{L+Z_oj5VbRa zQ`DZ^U?1SzlA%|tTHI+TFV5faIceR!`i1Ej$>yGI4`yu>LT}MB``5P`+U)wGZV7GQ zVA$kNmy{vjUY;)ZL12g?ecsDG?z70@bp@!%ptn}4#U9y7g%GyU(%9X;=6E~(ZA%Oh!z!*@19>F2@d^JIQ|fmuZ0?@PW?2yz(rTCG#r=ji&u!obcY+Is^bEY z9d@^I(a5?DcFtXbn%t6QiJimeWPKHAYrm=1ZOq!|mej?|8L<&=Sf@?s(qvr}x0;(? zyruYu&9X%uace;bhl6fIJbr%DoVU&WA^N?mxN@IKwBfu$2WE+iQd((zpw!B>nRI+ zZ$G@xz2bAhpv*RH`$@rcvGHMlzD}bc%9Locj(D29fTrB>lCO=el3xpe#RVxHerwN` z?5n(Lpm(=;;7&B9tD#sp>`-E5Vx$1GQDa$hU@91)Fr>OsBRkr^zKGkG!N~R@8hm{v zt-H&dtFtzb9`#zb8ksoVS=PHQlYvY;u|9iK^bEAy&2S7dTx3^mqz0{bqnt2cacXI9 zKhd~n0Dv_!6m(V};lJqKx|`9|JSz%yjCkP~a%ZvFzB95;S7MNga}wllZ0~$*z3@*f zgPUBM@(+FXQ?p&GJHmbKhbU<{-3__yYKf!}yYL)Qky~7&KU$M7@t|$Qr;)ZKuTK2sG9c@@_J$7^-^29Kwb>l$ z)McVomsGGcvm#VKvQTn<5mh%Zhn2+?IZwOe{aq}Lwp}kyGQ8f)LKdy?HWB9*7Z^h$r<-apKzRSCQ~}(ZwY5ZWmL|Gj$3}|XwjJwlp=eX ze;e5MP@b;M0--ul)ZS`+JL=V3ZN^O1yclwqwOKm6MqZ+0&ytRnJ`nT=yb9-E9 z@c7#+`9bg>ADn9xj9jE#yzfX_#@TV4%mFoK>&GFAI37h>DT;ZJq0zm5_~dLd`F z&0Bk#dC9KSsKC~mFMe^eM~QGI`MT$D&Zejxf)rKhZ?}+m$p&TeI8S!*k%Y(A5`-^4 z%k{;#>%Lf%_UVK@Tz%8K`{S2t3z+QW-m2@9wI=(@`0ka6@x{dn&a}&kp;MkAmVw3` zy$zp>EHiqitO&?YIM{v*!vlk%3VYO-Aj1HiNv}Vg>Z~Gt+hMHRTiPX-PJ&Od_&i!+5g)7>vb?_>k`Ux#86RhVeoJUx8>}8R3`>@F?2Xa9 zdBMBP)@}1GKcVrZlR45JwW(n~yZbo&bFs;1gm<_WwC~Qc2+{VZX5UQHb{M+PzSwK9 zcalk9I=jows1Z0ux9+Wrh!BwP;gHW-E_4y?kYe-Ii#I!)XWL`mzR+Zob38{7n~KP` z0KB^^*qPY9!0E#-mtysDN_vwOZP%{9UM%bU(2n<=1Wy49aG?j*@XyHHLkSD#_Xh=-9Wq?CKT zc2legyVpV8*d0@Qo?#xQw{c@1KOtg0QJD?A)?PDpbBkhg$B-NuXglH!>;kz*u?M+L z3(q>goMZ1c?TIJDvAyP7&KG4)ET_X~Le0*)A)${nL`il9f^<%lPId5qt8_pS*t;?<^~LnN;cOCaAtlE=q#SOrj_62`D(G3ZG?>w?35 zjDz#?GPfW$Pa3+pnMV)SaJkd(N3Pm z9`DxoI8Numnlcw=%>56~B%Y_i@jrU^7x3{zumJxfiWJH!_Q2-o`u9p@y{-G4{)%$R zN+!l1@9*vf#OAge+2a^4zwq%~uc$gb|G>U(O26&&xnft<-rdK^)Daqa+|p~=SCzbN zY54Kjqod0&frYN3TO(^ETLu%Lae(tAlp_wqP{wAc69Y{SYJS_prH%Fbvm<9&68mBz zVqwiPRy4*Du7+1ld=A2#i}`8~vzs7jBNhY{EU;w!F!KEgrxqKjrA#2>NxiZ#2Ts;K z=eGQUA3pEf>7Huh$RCPfeQ`C!-}U>Aa{&RM|8hj_$ES8oY-;}zp?@=ID}(9NUySf; zwK?f_Nna~{(aOHl@%E;e`RJA=Df<$hW7%b(c5SV^U%dYtqf~#3xkjE-m*==;;Kl4D%WVVOW5!eMO%0p0-{5o6yqcc6tBHr( z^=3{0zNtnixJ$&^LW)N`q2Ey4YRSWq8vgqW_NfPZJAFvQ(U*pXtue?>*oAylAdK@; zr*_U=G}>%h4%ddpZH;5N6>HZ@UsW>AgNw$Es_RlR4_+KbveY(4$kOW!JDK=LtNb9=5 zW8_8aLSgI$^TG30TkMw%7u=4EtL%)aUmbbrM%Y#&ydg9;?@{0HYbb8cmurps3%2B& z^kQkaNT%57`?ivyCsG5EB(s#pt>%l|$%!d4?@Hry-d%XN&Ey2neeikA-dBFJ(=;`( zU)CFnM<`fye>nC{hOea5-!d=AQ}N08A*)Q$=xuhw=JRAX9@0)j_uJnp_h!nuMeP^) z;ogf9V^vofdSFNh7lM0bcW8AQ(N(ZvfU|d=xhf)NJ9b89uO;&Z0L|&u}JF zJ?8O@*j~c1S=UMC8^^_B;F>;e3k9{5VP}v>wrCt2VtDvai!^p#4|ooDx`>-77cWU8LFKbO}aQb&cLi{hWR+2;(RH z_%4AkXVMce0`QT`wMP|&XypgT3*ax#x=X%!b^JRjqgEWIjk*K7GCE*tNVC(=6zdw? z0k0qDrH6LLxJ7J764{o}*wXfdhp(gxcIhr>DxVT?k3HQ--NbfK29F(j&OKY+d!?86 zdVoa|+{qTxm#sNEqnifojJ%BD*;qS{7YMK1K6ZVY8Qby?`-Ii7=&Y_B`3|wwRvEBIoRX3cHhT_hSmY9bwe7Va&DUugY?c`c^Z(Ki0Lj4h4 zoqgv#?7~}A;FeNp$9Nc~+U>vwY5Z~I)3XgmVZ-3?1mi|@}+3p&A@$Z zgR$M+pw|-8g(|PMoYcpwGwu}QuS3_23f-dZ%i^NGzPbtLl^gctb98+FWNp${ATO`d z&u;j#nAPrx0n5$IMVgs{vWNtdq}k?mj+9~+SRvzqVSSCph~OCx$Y{V>7lY{cL> z)O}#q>DA$j8#67V2c3|OnpN!*THkups*2+77~$J)yC%G(yk+oAL`0-_dG)03pdsw> zDt&E=82;{*|7M2YE4N;Uc}B4nL>}GYYwl|Atl6D34Lp74`l%(AHv&fO1K*!oJAV%! zq;1=jU`Y%dF9>Th-|#_uyVL9Ci$q)ANcU!s%FXGIv7s?YAi*MztNFPjsm4mCmbWZv zo(_6X0$5)iK9>>~lDfz(fwi)r>>Q1`BL5z>7^J!J24jPMXgnIR?V;5A00XD7i9R0pA#S_xDg{V8@>Dq{&fa{IAr}^b7_~!g|~LkzBqr--Ms7s zfGESO>6kg8Xu#Q-)g_|&-Dg+dFrxq{r{qkrv%=qR5=K~<=P%|ReO2V zX`Keu-Y;_XJb=02c*V{6AR@L0AC*5LA#FGNbS~2~nldG^(+9-&6JSVMhvILF-Ft#a z8%yJ$qg_v@(>IO6*eaVc5ba5C>4^Zy0xG|_xYeObFD_hke>lYtW4_T$+?88KP^C@k zD2e zC03{OlJ9oD5z>{lWrxUOhMB z<9h!&Kz&vt7GRq{ny?MMSv?tN9X1k6{@SrCA+@vH8Y__-%Au$nyoJGv32P(q-|q!oLwuS9h-3>9>cja(C8jzHce*9h7yq{kDsko344_YQ{Dv=fIAe>(0Tz z*f14!8^-Ym-)@Lmp$&W`7!^KfM#Z-!y9T*-Nsn&CAfldNIC%={!n0=xN!0+~$TQe4 za=~`%0)&sp%K@_~`fWI+$Yx5T2crXR8gz4UM8gx@1%V@nk9>{fnv)jK-wshUsdllQ z6MOss_c~-0&Apx-roPrWDCt6Uz98bTv@zr21j}gtJyw5!*;x;MD5$+%pSwhTjGXQh z1(kf+r5isy=4(Mm%zk1Lf0#1=!-}C(BxU|EG)2%|+sk{gMi}`DMti2`h#Ae!z>!a3 z9kXpv160DOt6Q(KYS!nc%q7_>U5V(oLRzY{v4vOnUQqfjI=a~!b0L*b>cB9&I6S*J zuG>f*KIl8hpCG`;&>6|=)A=+{%+98J6q^q-Z|tqKG@^O4O?g`pgTJSNj}*G-J2aM_$~B_bFLbIkUsw5zTB z@WMF}>ZOe2?efw$iI}P!k4F{SC>V*~?XB#JKiRx{BSOSbo3nnNy2zxa{tg;a*)4Cv zyb-SyKWRHRlw{48P04R>yqc3|B(8QLl+n}}+ShzCMv9?R99fQF$Beba4|0A>F=Bsh zWT4yja#yGg07r@2Uq<=PK2Mpmk8qDX9e1`A8BvAF8%Icr=eG>lRc+u_pPt<{-0>^*42oE<*fx&BcC7^-M(a~L(H?c8@V zi**xO2a(PcJS7Wl>uNQw8RA(Rx@vcAd}H^$n7NeoT{S^Ih@s!%v?jD~c60LbN-IDr zLw!zqQa5%kmZCq7*RDxFP<@vyWvxW6kxi>rhUV_Z5Z%#LB?g8LDf=${OOdDTV)Wk<2TO9R0u9 zNjZny#j=f0NQj%+G>@d7`G{^w>(?}u=O1l^{j$}MGejBWqWPJZvQ<)Lot+AjWTwkA zmLjlPYrT)|XK5d6V`IU%Lz4?jhj^}cRsj_>S#A&F4Px)^jt(5`>kLAkfpC?+Grz3a zoaU3lZ=6WW0*)&Cnrk`4Ml$kS6%o5W%GLWks+nf3F=$LJp z?QjP0M(&sEx~>~nRNVa>uuYTslKD&?$riJ6-gZg&r3)8k-rF#_b}_21z=PhTL~xvB zeN$0Utmr;kvq^@MOja4unFQ1pP%DlCPQ`)ZMfyY5LHyNJ4AGHuxnL&Xz9m*!g4UBV z_71b+^vSm=zp?9N!6Si!I<>rbvP>;8_E~CBheKWxpyMUAzp=H68?CHaH}8 z6UMfmv&y-R<)w2NaroYN9E(ppBZ|3 zGDRr(Kxw!=>~fCR-fN?cU_g5A& z5b2~mOZ8a$pZ+r#>pvi*-^=tn-tk2nJV98&(S_yLyjodF!e9O-{I6I2zTrKf6&W=fpcZ3 z`a~u`j8aH9n14;=_ZI&r&HjF|^7j+MSN^6J)jhC-u5L7S3;g`yi&ntDa4I5s|G44z zqkoh4KV$esF{-E8M{55+AsS%ZyQEyQSN<`EUvv&!Ir9$n$7FvF|9>*ab6qfp^vzDS zxe6wUU)$#QSpJQP{FF9z5ZGs%|9KY6|N1_^XUS(QD` z?0U8GY*;ExaeYZf6r{#vA3=7l$UAH>2Zo-VguL$g#!5?^2Ls98i@zuRnn=cs6iD;W z{h(|^K6LayW40j|mu?WIcCG<99bI)VzAfGKmF4gM?_EBook&bqj=`0cOzxox$xy&nyfQm;~%q#!AW=uVL$ zFz-}4wz$?OOwS7X_SFP$>SKpW;d+?6%hf1EGlSpO47<06Y(f3uu2fzB>YPunjG+Ja z%I@Mq9kZxq+Bgol${F}oX)qab6ChhA6MN77LAH-)P1SyGvR(t_pyw_k)Q$3Q9-hzZ zqUNBw78vmGJb4qN>KA=n$VEoUt3=a>^lbNBnqctjm2gwWW0(MzcaM}wwXbmYl2da} zjkgP*9^7MnQ6eJBPGs5yij!=F>wde-&nx#=`czWS1P-nbA7MFng;N_I6r{u<34d4{ z3xYGe@WJ;Z?(pO=A^AN#$JSdHLtf34mqNGqc>9|-4``1r`EkhZ!+K9@Jy9kX~TCfzbAV(z^d+p=IN z2bc-HaOfwmmgBZ}`~QWj+#u#woj!g1ie5m1%=1{hwkPix>=GKM^X)IF>(+0i) z=~j65l^V7CgUqF1dj+mAtoWQ{4#vwc5xC9C0Xv=|=Iyw7C>n^S(Xx_}kbk)z;CC)S zIpg>lf%^{x1@xN?3k3b2fu|gBzG-1Y_|jVF?F9pA%L|6_Jy}cjDOkLW)FT4_F+~51 z(EL*d2D&g$)w)Z)-c+AW=)e?T$m+Y-n?3v(>%I59`!ZPlNuz)UGo0X?-%ElUwuT10!z15M5;8GqhsK} zChA=oeJ34F zv&5hj&|646nY;OA!0~H$Cks!8{LW+eP5yHR0X>=50}hWQoK@Hg+iI2{`Gp0TlVHPc zC{~BkkdWU$*RU?kqu+lW)LxN$WS!@2ayulo4WkSMO^OAP)Jy`tlo6sR|AT`FAF#if z0Kim&?Y@3_!0NozI9fw?o0StJxJ4-u_B$+ls!qffyg`$t#_8Y2#<18(yoTir#BC*e zx97gndrtXeIL7z9_ykd11e32sBd4tM} zk`8=Yb2XRsC)C_KzoBCDMHTwZLAcg3zMOU$-(48JRF&$#8CGs%IZT9mj|tWCM{IiN zGMCs2jikaH?99WK zMXg&_X96$4QEkIVtBhUt%`S9Bg6Pa%!2-+cnG1Ku_u9NUuv8aYA@w2Uw)j?g zoL7W)4!V0OyR5Htf{ut@*Bfbcyj3EYmn*PuZn|?W&y_99WrDPlS>H5Nw%6jpj(Ms| zkyqnvfM3Al3xanB?MKeh%A?2STSkHv={L}Qiu=2$2}0FF2X*U-O`mzOcG1DPSZ1Yh zDNi%sI}7W#kRiseyl56mJ#}KLW@|?ZVJ5>RGY0|94z!#xFFLEF^07Hz0UF)uXmHYt zX5RgCR1B<^vJ11BkGy3R92!5r4aslWwLjFHT{p&H*4BmUtsP&U_1((a^ya>PG((h> ziysIEs#MmhVCA7>-4B1t?_b*&Y^ncdV=B{;pJd&GpdXYP$HLL31ty-p@g-jK$HZDa zh&je;(r!x?Rx2MVxyyY)Vk4m?)oFf3$VoFqP}HOURnep63%ekOVrg`+^SC8Djl_x= zOK^z9@mAMIR*xv!P|DeGh{IcYC0%+X-Iw+ZgTs>f2Utp@9JZHH-_EOZnsq0iWR>No z&+2+@X(tDQRQ}!P;2nEixCC~aHITtmGuZQ`q5|a6T2&ftkK&@XG|5CH-jxDeS=4pQ z$I}~gbgfbIsH?kk&#GTB&Kpu`A3ZjXbrkC!7&GE^$Xn=`Q%1`giTVJV4Z$VUD}(>>^DAUD4QMR*%6f^offi? z5IMO5Z#$YmIpQv1kE#suRNP>iv97`93#2uBO~5|o3~<0|&l8w?p|2F-8$R=;R(5@* z=v-!2!Zr9@#@C?aXqub>-`*ng=348`ZJa;hRP9+_#M{L0OqmlD2O(j99XLKGOg4?E zq15~j`|1$l0p3^lYYS%TV&fPDMe1Q2o@wggOT#`ooB9P4^q+UoDv%?F{D!k5aOcXDIh|dyxeP0sgotvX4Bx#U>SiH4 zbyAq*FTYq_48v8BX84w-&wx}RzBUDe5@Y??YSA6E%a#r_><;2S4JcIk-3s5ze2|@a`}}87 z&wftN54Y9zjA*WvJ`puDbH0fbjA-qMR!ekE^dd)CPtF|W@LwF6XfLrxH=UG)-LEgx zU;*9BK-TW)pulU1SC$>!e&dgA1FO|$JFEa=f> zYuxe!n>TGHA6}ci;t8F(0+Dup0)ih3&efYDAS}rjFNneL841Ll6?jx$yV2$9HX>H& zHhos_-hpg+)moc{_$Qs97s;Ci7oFqfS05WN$z`On5PnYhTFZ!)<#xlhzo zeK+?K&-mvL!i^foWI;YgWuCdCSaNIxF~!-~NVXlM^k#q)d7f{L52Hgp;T;no4})K{ zPhGD-46Y|efA}6v%)f#o6E2>}iiqQtD|0s*W!}NhR+WE)QEu@*Ff*>R3<8iWB7Lz| z8bIN*2dElH-yZL=kpiVN9y6sDx`W1;&W03J56vnnUXi8$PK!aEA*9+*_;gD1NY<8n z=OnZf+G9pr>bPkHwLF}Ts4q#Vby*lf+`+70fu|D@Yj4=uwwHR@iKvf8T#E0DB~ulB zWffx-{YBT%8xl`I4Df~i{K0U&HPq*BQZg>j$2GVF=3A~^SC9sAe^8IL^o5R>Pv9HkOZz+pTLp@Z zebCgB>>w{)8-9P7`fRPR1N$XUYY`&sufZnQ1cKVBCkc7E=5fl+pRfY%ckPP8vWl)G zo^?-98NkHV@Pi;(h<487OhfHY0cWZ{1Q3BCA}I8Lq}c1ZL;WZ`*Tvw`qemG!#d1qq z5>^|0eD90Z;SZ{N+S~00a&LS-gSeAZoG2Sa*Ad6Z_sUXJoQ%b_lbG~-RwI>D z=dy_dhZ?=QZoz;~QAd|9gd1Qk3gk>lLO=rp0KzzjndaKPa38;mD6wRtFnT-y3fse2llc$3h zrd-zAw1yz8jMJo9OO~~KZlzpaTsN23oT8NSptuLmzlfOhIv{-T>j*jEA9ql5QyulXB>{;*PRy(S?UCWUHy@ zL$GNHmRSONWhH#w>yyZkTB+|BXOu z?Pd4Mg(2}sbg7n)DtsBOslc3iYbRao1@N8KuQazng*sHX_q0+m}6(YZMJG8+umGS&I3C`17s06YB}q4jjzgSbn7q=RFE`jHBoxy5G!GP}ZPC z>XqUu>LX&ve&En*P7oxo@#$9dZYCKQom-$iN;ts1l_rbA+4pj`6*t)O2hb|OKNHYY zlb^IzIL}jzX^uoLolE}VrBlToS^n)`zUE&UgO1LO`i~tN#+R?!B$HGtZIrzbB|oPd z;6E$_J8olKGF!fDDir#2iG?BO9z1!!x@~8b+7wP?T9#h+ zE6=t_r%c>S7>AGr6O*2$4rA2luqf~P;&SUN(8Gb!^3269sfw4|O9$wf?M`y%&XmuM zT`W>7@=3|t)Ut=)Fb>Oh2}7G-^{PbU4t44j+d99@2Jg_i_CZpoqpkO*7hF(mo4#dn zQb>xl;_rKTk)6S>j?cOeNIQz|9v)&xxSqv_R!J#TXKq(eKJ<=-8J7>_CVTkXMAkSD z!WxA$Kn_7^P9@Pn^FTA;YUT)dPMS0+zU)4=TlG@CA6dj-DOa7K^GL!rvHk=afT!|_ z;>M4~%t&ttG&`gm+l#pLf#q?!_BBpw@|_ch!qPWgM6}2&q(q-32L%T-yht7Quf)OC zc~53JtOVAZg-n%wS{6k%eo}CCVI=~F@u#D*dB$a3vEM%jj4HZ6@qcmIH1A^WgN>*r zP7~yNllwc5^zId^zpPk8go@2$0AS#(6;+~`D<0`MJ&J4FzusZ7*6CSb5uwHjjiQu4 zeqS`$*$H8W+vs3FnARLF^UdZrC^gRNf=n_`!_+4<>dEj{5GZS@4fGrR;r=wi;rluRZ*5jS%%_JX_uKZ3{dGKWIxK54p2*B99XcJp zlFd{bwGAM!qI+|{i0L-1zWI=NX07UyJnfn+J{G)S4Q#s#u|2NEf* zSP~BECM~;6zE?@{)@(R&-X<>%M?2^S*(9=WXARVq)@Av~@GZD5d-}49|mi(jX~A@_(4!mWjE)f~Am;Z){Dz#WM9A(fW@ z18Jl(&p6UT+`?&U%7bY+cD99?W4q_`sZ zO!QZi@w|enI#K3%)OU19=5>5arh00isLRs%cxkf&*zQ4ulJ7FMRQ>{m*~*A=##Ol|?dLV4p|n-rC1U8QhZ z&zB5+~-8$rHwR1_o=4v(0|<-$XNZ}nSl{`mHH zFegy>6ep*U#+@_ce@C_hKb@XrVh!`@P5KQhg?nfrm9!ch+Q!DSd@@I>QG=j%qa-`}(~teA!~-oucT$v#Bk{Y6bM?g6P*T4yLX}URlmkyM?R1gwmu#D;{C!DHtyb!E%u1j=yc{w=D zVZqY9-?=mfOQ1(!`~2Lpzw|z`-sHk3;rv^3a4bJ`2-x3b@-2jnaPKo|ZqVUV7SM zJ67p*KA8*eFE!3du{Kw{4XJcXk2fy7@Gw6JcJrya)GN-F-p@*vOzKk-vedJ0AS8Vjlis>yl@BzC=?z0KT8G`~Tb)u{UGFV75J z#YERJ4r)H^*ob<4g^Hcdyd^}SzNf!FWa zZGz=qUPg%6JWM$u2#OE1E7p$V^~(_Da96ZE)^}O8m&;KF`#>-E|6%OCqngb6^=|>i z27)qxpa_b9N>hsTCQ1ht1f&E+O6VvZ0z|}yNN>`+s6YaQB7`a^J)uWB(pw04~D}6<_%E~fVGN+~Y zF`Ki;vP(+Yqy=ey+10hI-?KT-eOetT%wStktSnJ#As#p{4 z`r-W!9L#yAl|_oAF=OBF9W2qJ9Vu|X;=Nrdo!rKdhyESqDGYk!N14>z5H~aPHS6i5 zKu*XHWMwT0o^QPWOzXlv7qViT6!?b8o4KH`pY<18bxjBT9tOt8Cfe)jJRGPt?!TM6EA9)tUHl zV`S4mr!b{8IyUyH1KakPx^rWTMhn>IMF81<{C8X8;B5D&dUAtl%J5LhP+0<@$n5g4 zi{a09!C|=D&3E4Yu@=K^Y#rA&K9MGS52f+KBa9`hL6?eQ&B3M0WX6}SVud}|3L%zYqk3lI#2ffZmy1%I_A0^6+nci@5KKt!e>p5$g zoTR~mg3iwdoV<2uFgk0>JHYngvbmqa>&j6>Q~chFYsREK$7<`P5^7VNLH{s!8d&u47TZ9HFMJ3rU_t$g5d3TbdOIyr554}+ zviBGR#a?J_gI3~+$l*>+=nnFyXGoPgc01`1N$b8xGt2egHB;Cp%4B~#R!>9BQ#-Fh zJck!hgxU0e$SATt_+tIYR>`BtJGvQC@R9RbyMKT+)29cOX^aKX3K-CYl7^(cx66dqJ44H<$psRzNvn&&mjd(M?ag^y>K z0V(kG;3peJk7xOg>hlYk{YqdA(-N>*+@4uEQ|1WF6WWlR9%uxFoWH7X+|;y|x0%)c zCK`7-XvCa`Mfg5g>e+4Rl6N~>P8zQ}p$*#H@*bXJxAraNoiWB&Qs?*D^nR~+Wh-LK z73xkR#ZO9rn&AvXWWhxXx}lNIp1ZW-zPSw;?J{?rvNS!0Ss*^J`(VUon!T|(*IW!K z+so2hEm4K1$FtS;n22WLJKR^yV~0N3WSH+o)l zoR2OG(bXpi-|6|ro9TsZn3(!I9hDbXh<@I1lu1oy>=%di}8MuJ-wqZ*SSH^FoF zqhgCr;fs|`CAIGgu*1)fa5_Eoom%LrhrJS4*A-c$7J_Ju=Z z*?ObO$n3#L!NZ35j-m(URwebgQ9ZKXQ}D#{rkW zA{0{NVtTa4rK5Cy+(gV&`%75sdAYCiH|Gu{=C-=L#+;2BgPUN#9wSDwD@d zX-n-JVgU!ks(+__8W$hz1YJ}Nv`mB*`5g$9VAKB*rRTxVqm}47sYo1lb=RVLOXbyD zb-gHMCU+R;E7K*J;4VxT8l!p6OV4G3O8pi1f*x_EGEvq7`Iz|DhoV15OX%aD<&wu9 zdy)SP*Ii1g5nLhOtyTfXc1$*_r_YW?V%!u^Rs1d???3a%zI{>~s2uJ*yY%a&{z$(> z!x7XL-7@_JOwG)kx(UVd8dUDmH{2N5a0IlEW`F zhv(r>RxR;8pC6-(?RU0*YGK0B(bS1PJ?g;|8RSW^6p zBzadWK8;U|-8$l1^0{{KTx{DaYnUzZ0XU6Vb~W_7xNqu@$(TFbZFz6bw(0Ee!)&O@ zZD6Wj@Vuhfr%D7hjbJjW93C;guH#reDYu>iA^(j^AeFWp8jH3k9kpgW>(+-hnm$Z^NW#m|zCgf zeOEJfeJ0SCl_lLIms9Sk7v7*b3GF2>3qIMcKQ6)05PB*iHXYy#Zs&kgzQcP;*nJSR z@-YQRC#<1)@{8lw&mR`LmFiPgxH4I?zM%~S+_H27OB;snl|ZK-%V*&88VlSEy(lSU zzj%s+3Gks9R9m3z4c6ml>^}pB&5eLyIbV3Rbxq2K(<4&$LWyK?wVO*hAC^6=Vs=?;0bq$9>8W>}H06Kz%|>01!&66;Q zCXJ~|?>5~@WAo)$$jyatS-%#&M?E{hNTqRj9Kl(mc%RlkjCpB~n`s4>9RQA-i}FnW zekO$!Mo9-DEjaW>OLfCtZ@F?(lYRvu`!9;a5sc!lTg+bIR$W=r@wHg`$Q+rMGR!E_ z=(+q>)C&1o)c&eix9ugy9MLdp{sHyaVXDc=BkB_)2hW*yqa5qvq+OCFUV*saxBFQs z7E1?!D%L2yU$;E%rdk1~W>2oW_)MPq_|jsOLi>Hs_dvl9$v4XWk^W>k6F*GtqzP17 z0v&_!uCjuT6_*csZqrZ=l1rR^3BR6y@nE;bDV@XzJflukVnFcTJAA)%76HN%*$|3< z@wmEs`LgRqUNq-cDmbhN?fG|4LM9W5gwNDscKKOo1E;;xGi!NP0j!SG@~{};-)mH06$!NU#vV6f zrRIjMP+jASRDw=9CU@otC^Ot}t`|~aVYcJ7{6M$-%v*ifRX1BbQ8EJd?L@l&NB>2q zp02o{Vz$axj-bw|=yi*M+aW&Yfdxox~MlLUJf%*YNg(3JJrhTn1~y%`TRRmimzdV6_-^ zDZN)AmWP{jQR9c$MYtW4g@{YNAD;D&EDi`lrZ?0;x+-|(T5n%LIvsXNEPDA&&VS9f za7RjL;P1=ojW`80B<_Q5xDM{6)o{5$rBJKck8NLh&K2gII0;i-6qDciY3wq=!F?2D=f>umt^ zQSSbsBlRAvRN_b(w(07&17>o6U*?^P@&^g8s<6TFTMd4IJ{8e}WX%U! z3e=+YXe4#h0?3Bf_c9cgyC8iT>YsY)I6*Fwx{#Mr*X?^ zv1tM0YnlVDQ3E7fUPz~xxA9~Eak&^%KM)+&=tJQR2y;LIvhXR*{J%!Q@>|DmD~8@p zlI2YCTg^DXy_)jumEBni-HbEf!@RQ8-zi3n_YkuQ`-B;tL3R(99w=kw0#atLVM|fr zVpE!tc{!%B#Dw86=2z=t2dc_>nFrmE0hP{9$W#4UwV$}hhW%2AsycMHo;d93p+>=^ ztHYIwG0f}RDyby>xVUFg`|f!9yzWW38o2L%3_zerzdho|q`Ua~t)EmAm7+lre9>sM zHM=|Tg{qd!%kJPm4MeNFr-UGrd*T?MDqRunn33L%Qp zH*!6`6Iwa=`VusneewK|uRKTk;kAZIz~l(}c;m*|!{KTZi{M|c(+H1V9eEk(uaxX2y~?AN9ECBv zu3oUQ3>K)#Lv&Y=J8L!)*>oMxY+vhe?EqWMHSl&_%eQz@lc(zx6MD1iqA-uNV8D(v zaXpM+;t~zpALtk%iUb~}*prn7*wJ>pue*CAr5Fey&23*bHwOh*&t!kay6zib^;dvots9QNV3_V?y0OqDWVd}P2| zu1{5oZjO`JB+0R=0r11PBE2K~>!{&!b=NI`H!};ksHe2or_Md^x}L`ob^>};Nm#Ph z>M#TlY)!bSHKoPE3Alt&Z#yt2fz32z$id z>of2l&NmqjMqciHKaT`a=!NTDP7kj)F4>J%!baW}S5za=GlfKqZ+g%w>#5ixY7dPR zZ2RJ3fP-QGY^#d(^+3kMc@1)2LO0GTtzLzRT(<;5UuV;X?8)!_9?igV-_oNy|7$$4 zo-ne`nkwbk%r`6M`p);`rfmPkB*dxfv754kW-%ndI*1$bmPNk|P^z?!S!a<}!(27l z-&z%nlSEVj^=|FLxSJ>`4A}J5AR;Od2JbkKUZ4o;ocjvwo;d{HH-bL}B#oFy&9~ zCu7|<+pc&z=QT7^rrb|J7OlSfRt}sK7b)jQy!9d5h*vH&XFlL8jBCoItGjM2ED)L` z#M>jhzqd+4cJ2ozcX~8hZ(D3KZ{*@6MQAzv=HhB0Eu# z_8p8cp6Y$0S+6HX8C_V$q170~Y*{ACtH8va?Rohn1fpciWutbbI@R<(Vo6Nm+jH^S)yFbF)&x`)_O}Uc}~J zLR12s=+oYw&0`Mgv2FTWh|-@w*CY#uTWW++p9jtzGc=`|BxvTSvHbmS*nvnF04?uJHuGY?N!yt zo#M8v!O5&*mAA~;`qqTFRd&gfZ+h(pKKE@$)acC(E-qhi&ktVI1yi8(Qw0TOB6b2) z%3AbEFFRTj5AKCtz@KtCqB}1uHu8kH%{nH0wgDv%R(6z3Tg$N-6a-qmJHtuOxm2ZU z>9a2^X*(-J*P;LIH)HR3n~zO$n8n_SOI_s=TV9APe( z?Nx}R;2*BSucut>C0WdS_P3kMB#R>Hvut2hKxUb!`LL@Ow0o9n(fNf_<(oC(>HAjS z8(vdioBseLuYdW*wigw*8sz_QGv=?(xi51S?2NeE?vQgxLgi2e!>2y`dVMjAqz%00 zB_7BR^X3sUh?`PQT)DFI1yJV(x+g0Kp@7naL2~|H!1X*GOg}%0{gchJeB6dTX+kA) z19mUL6KoAvx8h5f+P-WKkQHww`_8{2-o#rUw&qgyheGES_XLgPEff2 zdv))B@66UlL){sVUg5Xm+ZU2o-zjTphxwfA2J7Y08i4C63eXn)^1-UdsPzOd!7&2Z zWp2cZY2QGg`&3wE4aJH$(6axUqY_GgE@%k+#+67K_lqq*!ylAJU)sv?q z7c<(5)|ZEmvL{eH((?oB`IU}WmO_XzmA>^wTdysj>t)4BKvkcqIr@dbu9cP7HnA}^ zbXDSF2|TI>To0L`-PbPlGJ+=SdxG5E*t}P+vs>~?Zk%lmWgq4JSOA812={E-G|Ut! zb&d7VLL%eV_Lj%XAI1_y?Jy9Hv_%g^zHGcLjE%F| zdoP4YMz!7BqBTmN5o+!t2HAsr9~^6e$=q#m1k&E26bRR4Kdd9l$#zLZxGtGBJh#) z5}>IHPB~Ns`L1jve3-}Pm_({B`{s*9$aBzAg6Asy)nXwp<;BbL`oC``|3*eo*gE6+ zITfM%O6Aj`_1}7C|5eIqT;L2%&NSw#Ay?d}xT?b2_zW;ttUp;H;-Rn$|H@7~)fmC` zQ_dzyI$E4_J5CsW=9PuQr`bHL+o}Ie;0Jn1`-);BqKP zvR=xE(WkUO`}rYw?t6AU&CJlw&ju?=VcA}X{>SVaVEC8y2*~+O@IYYCMwGYTgSXJJ z?SC5vooh;;O;X!7?p3L}hQ?Q~RzQ1^UT&m9^(7FSFVm~gQS{T4gEm5eC#zQESfY$a z@BFZ2ms8C97o-bl##{OMU>4K)#l!&v2b9uS6RH$3+r8aw(Y|4 zBC-0+=&&xo;Wp|GzkWY>JDY&OgL_c9962?{l4!?7y`4dn@n{Mr=oT6EY?e!w>M_<` zUl4-d8tITM!RoIiHC!XG!)6!0>g~_105cm8ye;C}wFs+a(o>wrH+H0?g;UpU!{H+y z$mQajW&)B_n5v-3#_*w5V81Q?Jamb!*v4jR`;Rp*UHh5BuR=OALEdwZImXpI)$Gq* zDH*WUc zc6;A3x0nioRn-+pLY?6BMXx9&d9SPQV3E|VE9-uE)HX?Q(l?!qEsZsGY z_YN^cb!it%QoF%UuKBR1!`FAsdM1Q2=cy>81CK~>w!$q$7?#;b{7U5jwiC}bP4)4N z^YIkc)UHg0q!%2rbpnc`ThpIbO=KD=a81$SOz!RHE>$iu0E*ZqwPft-`$nk|;& zh58nQ?S9(Oh2$8Lc%6TL`zcO~!P^}tF5d%e1l z5sh@&v%-SS_r7KJ!S<${6bx($-23CM=oP&YRtLy~PL6vODzzdDN#!sv54EIoh$E)* zR90>qgVQPVTsfu*T%5^78+M4>2if0f8s%opf6Z3$xVX?e?|?mWR+@b{*q$t<8GFhVxP;se1(*sx9UB zYALVwS2liQ_R2%v_pf(9!Mw7+P}%sD505n9;U_(B2w^WJyUubAk7PiyWx}#b*d2~X z{;i(qV_#ez{F`v&uK_8Fbbjc#-24An>aG0~myzK}hq4ImrLQNYPdU6X^ZYCP4#yQr zk+HwFe%2@$U~Ph6-Jko|+$FmiSSRk2N?3n6hDwx~u~=w8bsnNL%DIodNZJQm{SJd; zGR)JtNFWv|oQGSCeaT4iHpa^uf_mM*12_8NU|;G3HZF*oDeib^==nZj_g8wMb&+>C z7LF8J1%_9Yxv0JD{B{|cJQyc*VK@nr4DX!2PNV3mw0D$bXGSpG)EmRTgqJR%$wgrlA2{B?Frp76o<##o8WXK?TU0luWs}!$T}+WtA+asT zJ}j&YT-Lb?K0vMU^Rj-44P@QI?AIq`4}-$>t1{uz$MiclNHO6(>x@eqFqPT~RcKSSu?`jXK^7)YfnriCLdgaEslSsyv zw*tDTtDNPRE439d6VZg2J~k{+vu)3g;?w=Hy({DXiW}~lc4fTKY2_&^38qN_6?e`5M{r4JYnBNTncqRf>nr)8HDw#F4Xz{lK&;YyC}f}eq7+%L?v zvXDqHoaAhDFFa5H0O{|fi1tQw;H5%hS4bc3d7)L%^O5e*b*=M^?w?a#r5Fg2KYcL& z2XR2(Xif2t5EhJtjlG{zlzmvpO2_PrlhY#gS)8@jLNSTJe4Ys#9ltA!IR|x?oh!9C zlqG1g!G}D*;aB(lhhiyp(MT=fd{IKUn{&8R>(%8kpN}0ffc99USJdE_(}6N zFu08itm#HeQzSzG56XOVfwCd@t+L-ioqz{-$j%jy-iu%+`I9p&#v^-)g-eE((ccBk zcJKgsi;*g08>xej&+p`(eSXf}cez+2Nk&c;zeC5)bMzF~{`;${M+A?QIdkLmz@|od z0?6274ON34n=_14m`g;QAE+I;y!TXyew<|ORiNK$%=OLd`Y{oMA#qX+_h`bm z}U}O_s%~P_5g^0^^w)(j;*&ILA$-)fDbTtrUAUM4pF{U2GRL~;(V?Pk!?S}Ur zVSgQ}AhOyc`e$S%C6Zv*xB^sds;-9 zB`>T8m}D~SF`vnOE*qev1|$Q#=h}BpG$0x`lCYJF49p(Ax+b4JZ%9>}6Q)-hQjh?P znI^}#15D0(dTPe;UqWFjmjdNMi4nw9_QTO>{wVu^4SXyhw6fYmVm|DD;AGwy`ahtP z=I%lK>lXW`SG|8FOvXsBti~^d?U~)Fs48KYi zx$t`yaCh4nT6zUo8_vu2R|Uh|ffwDXVkMsCytHMnw1m5~jeIUl;$kFNENlCqPr%|HfbJ)Kt%1RIgiR1VDH zB3m_P63gz9GtEmjTu@2Er;s~+u{ce4NeE27Bc+^Lr0Y3<;8+sTiD+-UEUf~|kRn&)Ix@4G)xs@jTx>HTcxT`1x%s@e}zi3OFi?fphR1`}@sh|t-W zlG9>(5l}k0WU#JLUtbCcwTK+^+)o#4bxma#%^7;E?`ySm1=5caE4U%UKH))*;K`WW z_S~|W+zPP=<^3A-bYW{rz&L#K!A`(RbqNEZA9T zB&~jSot0@fE=mNzj7vH-*F8PnwhEtP&9F7DE{T$s<3#&04|kLYY{Rwy=I!NYH|k{@gdAR!Jn(Gp)e5;tPHQz>Qho!8yViboaz94aav1r7yIA6<*cH7Ha8%J`O5 z{CZ)_y3~(tLEazdd@e(T`G*H*Y6Yv=!llMXbk{2Hgl3J*m(QRAlvW6`ulHjWE^?R)XYOLHW{QjwB%)9 zH_dbtbRB0;(ku>WdP^^>M4X<{sDh}<+d(lwIO*x!>#5U`+F)mhyL5v_QHjp)J7ZMN zfkqj%+H7kO?&by3lWLLN@l!F)5nM`OIBQY5-IH7?1OmfWnjANCzpp#0C$bp^6uP?q z>|n?qAlr=feioZ=HWs0`0c?(yZ-hXKRv?VNVm?N;)q8W$?(V8r4&d7Z4tDF4s&A|kixn(RJi4yqDkyAmQi~ z2;)S!W5bQhocnEf)BIKR3<(l0TVL+FnV*OS+;%lGf)o?nVsbjE2OlrdZX~REt|u5R zhG*nh$j$bbRyR$)v~I^keN?J+z7?<2a4Nh3D9uIMf0Su<-F5T67cYiFt0HdDY@#m| zApvKU2{sTdeMXY^X{_>vC(*1o77u)Wq-tqGc|~RAyNoFB_^V-ZDb~+c;|Xx}B%>VL zaJ!B}vp@F`Z+cxE-r#5az*>wQ*g?mMKHT;{0e0sr3|ys8hV!C73I~0qaf}8d2o$zvEAkE_1hb7_jypf@;;jQG4H^YXW27B2-ZOx8W2}mhJldQ^##c_hR%&p&2Dh>R9 z7lVJ--XQhk6nHrot0k5Uf@%L%2SJYn1RD}o=RoxGY0thrqn$bW5+z{$!xWVm=pT*> zwgCH#HcF416|kzol3`<3LQYbq46Ry0$-E(aK~wu`@Da%zl1@^8%MO>zWK#4=%jHB> zXi{fz-TZk4cE=6lRJY?6n|?=N1Ca^9snLKP+tiQ{)3R$b-ufsN?7y10QYPTL)FG26f;I_p<{j>= z-DN%f_Gn&H{re^a*JhAYo)=$!m+#{mD!{X#ly9!n(EgAtwTy9PS{ zB1eEdZ6n=xP>z)pjohD6p5HcHLu>|nb=@9e6M6rzx~nwL=#uRd5Li>O_+js!AThE^ zy)|*EqBTkAyU*ss)t&Q@@1L+&bZ3uQWqVOqD-4x9rVySTzOzXH8!Uqd&$s>DEH=Z<3radwR8`(S>SuGAGPkSxd4 zMJ&(U1#2_4hazFdBW-I#4!F$wE6v>nQ@*K|(1g4pb^C?P*1ub1XtBlN0FL|YHo>LJ zPrtEozt5Ns%2#G8ePb^tSGKs+-(Bp(SVn8#IjO4Q<8_-Zv9|0;w)R3=Z6~BcV5M<2Xc{wti*NK;YiPW)rq^749IFy?z6!aP+R$Eeo`^0j zp{b)E`ara3i5Krmfy3BF_{B_kS>G6cX}^=4;5${Unbd~{*5Eg|?imT;Vmw4_rz;$mjGbly>GYQT>9Ro{Qw3B5i|_GwIX^~dt(g3=?-@)jBW)o zbf#J&$lfL;w!V_*UvmE%#9q?m;O?ZZ{}p~@N*VR9stiEZUY<0$qI=CmKuq@v|2F|# z%IVh=XMcSQrzj#oJ8nW*A@!25onHF;rI+_U#s|#U5Y3g(c;|!9mvJ45Co}oGD+8w` zT(<~o;>P#-At0R{e8RNiHoZ8ZIzzn4Dop#p%IA`xE>i$JqTr0s?)~eZt&R=sX8Oa?P3d12WYc zj^>Vq8BOCo(u_fVURe~MiN=Y)8e`{Vr|9zY716S3DEbndwQV3_9@EuLcvQk@tF^|nb_BAr0POa4 zv}NUobHgUQYf_qYzaAeUz`YySkUQea@!;^x(cfjjpH}$)pUT;OTHICq#?lw#zRn1K zqmoqD5T)N$0;mJ-f)V5PlKhj?2^f_AMzoa(S<4pMb`-0lV(Pvu5 z%c{}(x2|;Zm7!+l*Mm9LJnqfrf4FigskLEX;GxLf=5r^$6w&H9|M{9*79hk4ftk<> znH_2P+C2{`wSw(CO3dDvL{}d?bpT;lWhLCW_qjZdZ?Y6SaPTW%CoBx8#{g9rPp{9ui7U#7-E$4H2grSic8}@?jN1IR$nSxc7j{r=nPaRAVvoNKmjJD%@qo1O zr%HIP;Agp@-?ISsB9c*w?`1&S>#cyVm$$EeA_SV`cx&aBLkhJ#%7sw*o#Vi7>sM0r z-!E9E#iX;C#Mv?bj_c6~dw4FXqb^(u3S8J$_1@?PdW-ol=`n+4Zw z9xVc;W=noSWR`b^9uyYW%Z;8dPAE|c-tvyLs<;F(s&FMDVXj|`BszD2IF-!qr&f62 zuPB$`3q$~>eo{M#2uXjY%Y@#qSx(KsbZp$lChq!h?MJz%W7k`Cz1$nLfPHsGQj0A# z#;65KsHR==Nhi2;j@9B!sET!5j2%oX=Z5y4t+5Fi0_6ZvvVpZRuNK29g7Pny9LQT7 zFY}C_k%hz#z?;rHV8q)a;p1yvQ*;2#)Q8`Ni7y6f zg&~L=7+AIUFBsajmryI(rIu570f5_E+g+e0$-19&w9-V`P&wAksnRY5uSu%lxm#~K z&PtQ(+qG}aCNqsc#m=L-h`3Et7v>@N!;vKXWa4l~TzGME=^cC^b;SI7deAVho(%2b zUJf`v!4f}A%GFfuolERTD4iouj~rwYGlnvC2!1OYy>!O4Yu*mlWY*jvz=0*~eIytD zYF1uAM01K{y3hYZf(Q=R{}qJ%ew*^fji%Q*7GP`E(*Yt)nec}U^^Yhk1&ESQvGD_` z!}+X0RgmD_r^}#Tku4&xL**hm(}xId6S6_Lhal!D`pXx_xOc)IBl)O6L{PW69-cW4*#hN5f-pyXiW0vS9yN}A z`_BtQ|B|xrm{N0R5aGx-pfpN;Qx-+1((%g~D7H`%ZINPD>#1Jr*R z^k(`w#NBlNm}@AmQv#}3JEpdnw7qh5$U-x)KE8^s3J2;M?MT!eIJPJ5S<*}W*y>x! zAetZ!csFPk_M#vgI|4&}13j>dO2W_7Kc5}9Y)WiG)eZM8xp&>ov#JNFXg6fLvdpnt z_!n}avOknelBErA3MBB5@(eBm1){)R>A{<3#s zdrE+B2!OO^y^Yqd9S;tAZ;(Ir1YgwL$wfA&=&>vwPhcQ^n{_6|m24lL5DM3qUkDp%5)< z<-L*_%Y`5}U8u5GJ@&+)x(Cg78I0?sWCucfplh--{Z1xGft~U;)Hc^) z{`~hjpMWeSC=UsWCn?z1&zJYZXtcP2a9I<($TFOZf+L9XShdP8pf1#d5N6{46JeHX z=ez5=1n0Fu$D)U?upYK$wC0%FjWr2_!cTyjQ4pA0ujn+;M3-z1TI$(!rGJ82<~ZED zP!Nk84o2wZ&xL@W&)!HPATMvuzB<`H*>NP=u4dDi;n9Ljt zX4)!8Bxxw!{1ea-L;O6S-QE++G&P#2G#Ny-hi-?gO=_8mGRUoXRDvda1tW#l)G3Kb zCDqzh3KEVDN)3(^C1>~-0i{zO%RMAmR=uHq357Gm?o#E^vAIhPoMQ`Aa>Zc28nxvS<}1aoun%2@F9 zeOX}if+SX=>P!fuFPB9Q^$L3q^m)(@yG_yUCHlzcVyfUfb)j-@jI?umQQ`rPdBH&X z#tB-?YhyvxeeIKBv zS5GdaxhXxldRW$ zAy!5V1h}X7qBN7fL>XGQHPPYr`?dSW;P;Mk6msbOcj5X^yY$s46{t=&4u!BunPunI zgB;Hg`@w-m!!Tz>qBN! zB=5Nqzq?a{h60groC`lf`uTa8b7TPTbq~ko+rlqhPphp5-%ol@kci0LuEZv0pFLewF2=&i@&|GHF~4wmN*Gi(ix>==0r8 zwo9Df?~0;xKyeY%1;>4vGmJwX$XJ13V@QZ-FN0RabZ&=&1m35zlfKark2Z}ZT-0)` z0u=^92DdyUs~B1exhv<=CXy>GJaA4YOl4kX6)$&C9&!`;w3FN`WVH7En*Pv85)njF;EI|k|6wpgp!E!Ej zVzQI{GXZFlXux%81!~7w&=uT0tR+!oDYsuxUNAVvCYpGADcoz=!6Og)h+JYhj*CBx z-C>%*f+7{B-;$`FEX^#Au~CEC<+X(sm57_r+A0@e7t{*-(p`bN;F*i|}jkh}!^gO=F>tXnLX1+tHQXR2>lXcKRoZD^&L+Q7b@pU%Z+lR^gBhS=$e=v(!>4 zK9|yzt}n(Ngp}b)Yh@>Wz1w^p48Ho~k;&p-b3Shwp~pr33TOn*tHA@R{=6$Tryu>< zKl~A5zxj8V?d?y$Fi(g2K@X%+3~=u#U-QS8gzc?HSH~?ECgR3uJl$xe*@WP@`o28w z>A7ELL#30_<^JL-qgUXC2KI%C%_pq&D1`yuUVGObb#)}Zo=dWfRnu~+-wqW4Ep#_c zHl`$neOD%~8Wfvh;(9}^g6DRUUK-AO8qshPH(UE$rYl6*?)9;-W3-MI2}grC35uOi z`C}(uSSB|Hq$vE)9)HeFByVN71BZZ5*@?!by$68V9srl2AY57iPF-L6+HMcCWp zIMz5UH3vbpW>D>ls*tryr+Hf)B3X>pFIoWcj9fO>6G4JaU|K|U#F zy!77tA+76Yz^o8Zi2F5tfuK4aBUZiHaY}#GYka4eD0x-&@Obj_TBjX8A-J>b^&4kh2RbRs?i$(73RNn|vIByCy%ARdQXmHf z=LV$$Y^^ITh3J}j8MI@TbP#X2(EBIfY)@7O%L9mK1bskn!3RVY3LrPnMwozNv8Pz( z?&2WIN6E6#vh5mF{w{`8hm^b8!>QrbAfm?}q>({IF!r3}>T>8&y1s1?>f3Ll8C6mA zo;X**RGF28VVJL~eJFBlqz?y*mdQ4^z*>Ntk7jhD=)w8!W_5YvC(1@C^;a2D6_*~N zE4&8D<*b+fK00imqk~oEs1is2VPLQPuggT<3d(U1+{I`8Oc86%z42u5$?0QgKkwm_ zuYOkPf3*`?gWSC;mEdVhK_=rHx=UM=!F?4>nT)5edm?9^-tpoF*md_GsoJqZ552)z z`}|E)ss}CrnIPlsUrIVTplC>x_G-qxR{y$cFu$+~HzgKeJi4)(KpEK%kUfw-B#!n< zlILJ%56CNT7U-5AsvIGf+Ni+hf6oF|lLI$pcYo+U_*|cb^09(Lp;6_sJ7GEJltZ|^ zy{PE~P0EyZ`@XQMz19E`t!?rqIkN_6fip?l{mo+48CB65J(78w8nY4KU=6S;?*QJr zzaAToUEp&&Rqdh_`geV!l5`01ue0@u$talaP3z>+zj35kd^sa~a9YZn`W4{Hd&*K% zgmcrsc}$Uf@xIRrizMaj6?$f7c?o5T(_X+t9sV9f+10i+)M zbp_S|3lAswq&8GmX{YDh?6zxHdAf0@#dRC#Hda86O1ua&?PYul>6UQPX?7?@LArO` z0J0-NP~7Q@NEzqu;=CVRFNr>&W~pb{t(x2mwb&n<+;E5AqKa^<2sZKv8#47H4*u1> z1`?|<1FO;`h*MIU#U0*@P=Xt~U+@4Hhn2qAK#CQdgSQrS$a!e#9+iRIy}FAJJ(K`? z3V#gR7c!3Wq$h7~1+q7*Wf1+!LAgcuH+;`wfzHv;r12 z5M5;&bo6=0=04}SD;6~>T0M=M2(hQ?i2g*yY& zZ>Y=Euz8of2H0wmMILeH?gn|KAO@}1amo)uWa41O8>9pINb4W-Ui8fehgeTN2yW zyQEEQopnjvUoy9qq7Q1UEe7|8;gG;83pJnK7o3ZQ_=pXxt<>VWQPKNzq=n4Mp4* zNrjN?CVuLtkZzJf+iejlM1(2Tbgwj)q7YNEWEUEH|M_O-n;Ghs{^#-ZOf%p6p8dS% zeZTXbGp!Uhw-u^6Jt`W7TasgzhRWkUc@Ww?YX;ZDfzg~)t!*=v5>x13lr-8akuJLw zk}0mFdNQTlIMEV{PPDA{*GTc-2e1>aj@!! zlS!Gmn7;v>WWqsR)U|lU)=K6M_2RlcP-Ga=Xx!&#!0j}oTP;$pXj6peD`O|S%*`u; zyyE6v-?_WY4=T+KUt02{oIdZEjm^sqtUo2&%!J;wP=lgCt!=@9O$%38t&}|K z$}%h-I9SrPjk(1~+CR1I)(OYWmp5p7rTYZv(W-7n!z=dV$5qpdKG`AHcY{x1)-|rz zpSt0#0^#f9>xWaQ;g9oM7luDhS1}jExt9do+*DzGW<=7QMsXAGvCd5KT4Ug|lYE?W z%wFxU3mz88iBXig9r-xRpul2v%c9=JH^O?WU+N-qWyA$`TU~T?P%g0Wy+>aDN2OIL zs<|flWb)>yriA3s`ok-I;E+vgk&10Gu-wzl*h=za7W(Mlk3&w z*$mNzlQbU(-JldklzvGJBm8n=O|?!61WtUp8LV9vFJrcwO7qe0jO2T4Qu~>=`Fof<$(co@v75?4}t{q2|5nxjo3v z=#>1kKlQHJ%yf>IY)#J$CT!M*dOh>(UR52w;CC1f$x53(TYqkN;PqgF7S!I^{8V;2 zW$BmkpH1aSC85y3bF2SUQ8ybEt^gQhftFPCXnu+3aLR8X>OFIp(GIjuH-VMh*YgTo&VX!oulHJ%9hogiAu^=&&)n47?Z;UY-ah4) zgCyzW=3XqD>@BDbX_kq(EJ*e&-NvBGiD9H>s2(7Pv?Tm@o|LC??x5Kq@ya!bcv2k- zEZ|aw{q#zzT-jk&?$OBwyy<-_un!fb<))QXshY{A{Z~pB;&qoWsJLes`a`)Ok#fPPd z1mWyHlgt$Vw>>Z2l9p5#Hs-2Xm)~Eyt)$M$#yL!d)f|)J*Y91mFj80gh;z*qI?{Wx z_4NbOEf4f<(gWl}WFy7(pu2npWOS^8LZp5Kq?`_|d2L(!pRyG?@kWf$BoBKeH!fw~2(#6(K6CB~RjS(`61GY(9Um&8b6egH_k@8A zr@rc$TAc7#*W(NAhqDV`WN!WEQLOxPAIsD=xe2}2n+u>g-?mp)Gf3q)cNMw?^1}EO zOM55x#uI3hfVwt6PJ>zCheTM`$gwDBcFfvc=Q_XJ-#YzB_uYjtn<#e ziqzW6-sH-f?f4J#@#C{;lE~5YM4L^NH3vSv&`)xO0^i5(d2U!z+xF4bqoD?=;gVT# zOI<%K?Tq8p8&)`@lvnp&d`^l-Ixr|b_VbGU-CxWld06*Q@{(t}bs)ttb#2j2B;)Q< zMU4HG)|^#AhYBAj)MjVg3?p>FT?>6%E!MNHT`%vHdb9RY4nIjsnb%>TyP(&<+-d&h z0hTNGK)F<%q)ul#PF3>}$x`4QUeOj2i|l`+XFu8Pb5r~%fetlWh-U!npGYD@sGdb|#aI=fJ6#@}w6TcCp=M3&^`r4Dp^ zvNj$uRamk%A7A~8B-LFst|2EepQ|<0AFHv3amn<06YEG`bTEpdI^ozWLA6zSmz{~(A zCqfHPY)F6_jq&5YakS6@-b>A(6tq^kN4@)h85Xb`RG|dAe=b}hjBlB^*;F6J}|h; z13h|ud*$qIp&$gK#v~l^g)%B@CH6PSci+?OwjV)({(sD}K?^3>l;AIn+s&deJ4N2k z@=hhcS#+J75k=Jl>AqO)cT#B2Tw#oNmPrT#W(hTn3Fh2FucK6N)Jdq|&{Q-Z1|GLq zhq$ecG56qfgw7DZKE{v$n=u1;S})RGmyd%j0j+~hms~Gu9z6MuVmvA=zDz}N5KusI z!R`~PC#pc-ObQ@6(F0)t@D6rY5e(;X9?A{KK`R~<9;zH)XGE1Ey-}@uz%7T%vn|Fx zKQ?=f4`mch_J}Af6O8q_d$>qf+%$==kQp@q1tL&vdOA{Ceu~j&p#nWygguE?QbV8r zjzsJ&p%clp@@o+TU7?mIB0}NRBd{m>d`;fCs_D0Ja1Ak=F%1QR(;=Zl z)z7J&;Ay!&fMks8fz-00cvSq@ zGU-i70GrJ+;cjIvnFpd>MNk!n*yx+KAeb6zJHx5)Y?BFsz0gn2LVgPqm~;9adW7l$ zE1VH7e0)Az(DcoKTfGU}cg=Z8aLDQn(zP3tI z4e&9P(|?(xIFrE(!bL}YJ%GD{@36VV@-(#+Y5ab!?={j;T_9r8GY#xX?pqA5 zt)u^Zi+V`$BoZBB3)W>{oa9_X>&8N9}6WQnL(pruPCxQ^c+E*F-qj=YaJmJ}0n z#Iamj7WmV%km?b~(l5^FUk?D%J)JOVjRi6WXX zrM~t|W_bLMHRB_wlIy@gDb!2HtJAc8Jm4!;LQpu_DgV5auS%-}t%WMY|0KF73iTK@ zF%cXD#zvP|FFDG*5XC_UjG7;8(yWgtA&P^*DB58PYb ztR2b^7wDuZ&*bU`->R+(?>L}psFpp&7i%rlZlW8urnO)QU+M=dasbo}dE+PZsCGeu z!PP>7k|5%EWX`BHIGumsot`Ow&8B%v6dz2V*ym&ZDO1Zjm%NZqW#5!ePCMHzWCbU?BXBP=uV>uLah zD*wQwrzE9s?m)zCn{8`rdUN~6^6m4Icl&$(A*@;w zxDM+VQ|dXpCe>H&KXrrwG#mS)24ire{`*pRjescO2KC6Nod0T+{gEXKD1o-R&m&d^ zUL!Y26wmm1W5Hm*fX5i**z@IoPb^gUCFDnsLEI7z8Q+}3B!z%G#u21ywgE{E!}z=?d@ z>*z}c0}A>Pkquvi#p9cBe0kJv0tC*Dhzb++g>(y~r$Q-<3S~7&*k<8_{7*lK zkP%I}k_J5eD7CtqClUOwH09Cq1-iZ)7l`1%vrHI3Gz--K2?_r-8V3OxbmIDP1z5p| zUcB=s=w13U?f;C8N;N<#O4v6@a`7`F_9RlKSAYli(|4m9;N&}Pm?0}+$pETaimHsc zsGtPOfrdffGE(|HB*S?*?XY0O0>kOyBsO^rDzFLpX0U2%LusQkFB+Q;d>x!SDkO@J zL$GQyfC^pO{^gWu_$HzE<8$MSL!(TL{QVS-@K5!_)92qfv~QY^p<>Y$YfIeUcWH?- zE|w_wrX!gH}? zEF3LN%-0g4y8*rlnpq<(AKdsr3DG%d3))cRd=Y~u-qK-92!G&06=e$lClTupJbh`AJTh+Z)eiz6*2UGDVui$w8+@bsyd%CTi3vhg;_B2mz;Dk5s7bZIN>{8Pdgjhzeq^0WkIqlMmBSfV7hs{AJa~Z~M;cCmj zz~W2)tPVw$z7)pFO59(IY6Q?qZ&A4YEd>&p4YZH_9!74h#mSDbX8aEb1wcVe{m}-& zpIJoq0$4&@(AEa;@P3;emiyaSdmLk8qi1BW@5rDALnI+|kB7UAC-O>$d3{qXQ5o@g zBq}u#PKwUh09G2G&y-V0-g~_=X`1c*FaE8WC{hVO_t^ z9F#WDsFr_uR8-iAL$L=Qr&Os@Y?hNR_mQAGi;|KhC$b5$T59^gEi2rP1G!m5_Mv(hxOVza4!;FTbi{Ax zI+Ozsbl9^|lKBSyZ+h5HV_$z**DRx9CbFWjZN)!~L%>71H06bwzAxEb+ahk%sdSdJ z{MqMI#}So{W+mf4;{GGm+KFouup^yp*IeJ%oY2s=*+YL~=ofK+{FJ6t=P(K)V)XKR z52^Q&6J%vo^7B4cn2Zb#oM!PXj^QvdOJSU>A(FCgGaQ}|#Ty+NY8xzg>THzfB5xRv zdQ7{`*oEVAOj(V=g||9%yP+79RS+{{cyi&F{^6>Ickh_@ow~XOo`Cy-t%Ys;k%BT- z;tIn%bX#(&^X{eP7k2%YdU-;G6DP4!Sx45duWM&_eP(Lhj({)ORwrZJY&pMDW{sO* zo&uHO&&1a3zULX+Wpk3#{p#S9ti#N~TCbMAriXQz{zn#XtqL9P>v!vBW_HBw$Q!!X zUy&c+=R4dTqcc^9pr0tFfBVpcq1{{xXs6`@sUy!j4*52>e0W$_DKkw+Hl@uq*MjUC}O&jp>6y6oCz=6`;whr<%HSzLxqshlw^5eTfVPrj10+_hYx0Y z+wN;S855l`xIL$?zH)9V*907MefRdp*wvAb$F6b^rrq+f!v9mN7hG6RI-5y**}FZQ|bf|38Zinjr&Z2=u` zOfsi!Ev#CR8a*K*=Gx|nxU6X%`TKnG?sW`SOdAymFmffHt@_b&t*y1b>i*lxynNer zxqc(PoSH%3a&}kQiKJ@<3u}{@*!oYlTld%*W#2%#DnKkztlPjYqV3LDT?6eKt8OkF zvA5TQ zFGfsMMw+DC_;JJt$eBU)Ra)-(vgEgo^J!ZY4gH-jW=L*2IaWT`eRLx;1Qs^h+$0FP zsOgRRL4)9N?xBxfj?;FZfX*W)W@V3ca4t5uElYnOnFI<1Px7RV8^2%zDj*`#B3F7I#_Dk&{UN;pQtfL%qTQKVBPq@8r5Fc9gGZloIq z1ID)Rj8OD`_sacmJ3HrnpZq=bo_XI-xPv{vhG~;}0T_<41uj zXz(SYKmH*5D7clopvAYzTA`!! z1Sk)e3dtdc$D{?v`VM{n`gv7ys2o#@8~*i&-TPo$gNHKVk7ob=vp|$fyy`k50ioTQ z$20_lhmVt;2YLLl^C8Hcfc*52uiMu*sK}W1ZmaM+8&o0j7U3_0e}eqP{%3)kVOu26 zgLaqNTk~_d$8jS379jc~fAV&cH=6D42&*RJW!YQ!H~YgvxzEE269)-KSohXF-+cM- z_1k-d?_T|;2YUJwL%_EDV&1k&4l{NV3j*~Q;B{U<=RqJ`oGU`1H9N+8A5+HeT)A`+COsuk^^k3?`2k57a->54~MVI{hnG7_Q>^H_}fIuf-0h) z_+C1^yC3aNlL{-4cIX-_{_gjr?8y;qkj~YY-@DQtzxXG@BH5x_Eua7yJMG z4^&rnOxwM4@b5mk<9ZwA$FvPQyZ-;rHm;-z(L=9jqivqb_*1J}Q#ZH8R7f~2e_IDH zHm{pk1oAyx|9no+*g`&9pm2aiqmbF|zey3#TVxsN3z1^sM>d)Dv;{Z6I5+CE!81$> zjztvV1fF{+{s%XSmpXjYpPGuz%h7o=6+#H1*_vRgUs>_-my@xDS`+e(kH0W6NZPv^>shkf zDe5y^-s-FuVRLd?+HjG{Z=`>#FeBy=HKpwN!*U1+xl}=YzhcdvIsUjFS+t`Ix%xqI zuiQ1Hhw4wi^O?1m6GnZ-fBEt9Z8KxAd)u z)j!f5|8^f_@nh$0<@_7dz*aElGeH&Ff#F3v`>wLZ^X#J?zrwG922b4{QQ`MMge$LD z*1iX30c(Qn1FEqe?s0gWPEY$a`99&q+Y@RYKv=Fo)Hn$}iB$SoR>$|Wxle|_@DC~_ zx}~2fEK5&*{>~ubCiA{K_cOMSr2YJ>0Kl((|N0JI3jis|cgA-={9UoQT zi`kKzdo_@DA8>boU_UMgDFge8mcIYAV_9|-kIx?b`N%wA-y|rs zK46cQ_`>7itOr|Q_yjqS3SA37d38_J+gkog)b)FNiGKrZ>_fA`=KFMS=iNnqD=ZK< zkTy;%e<1ex16D*L^52AQ`UNnLsO7JG!rSiG9DTSxG|zH=1{<13hKbaZKXoSH$6ZQ z3SPbcfI9%_eFTIpECMIkF+7+Vk%;0?+CKa*U;v9G20$R?mHiK_jEwc5-Va3hwf^o) zfXTzoQoTMre%7J($j>?I0ZNR>RJ>6;8%2(m)JOaz>;t$W=nx5j^7{Jy06fOC5cd35 zH$VBOAO!$i{Hz(f(n?~}SNp;H_QhXta+|yzgUR6q?1O9eFOsnDG*>JTy8Rw`@X{Km z2BbCa)L$R@{bBqE8o7#s-x6?=9Vkk!IN9kc6U^=5%kD$J&p6tz1JcROE{&b1;A`1YvW zz54&7PWZs_i@Zu%@hd;4^q@+TbFlBr?R@wZ$eRuD42R2cHM1R=1k~`P?@a1AnjwlOTES|Ksbn znf+=T01dG5KkooV_xPFDg}?gX0dksna=f?*i zY7TvY1G^HS7qZjg{fGB<>LWS+kL|7>BG_p%xB(PTOlbP-OMqaTXPbXYJ%RQApC9sT z>px@VZCX5ja=X{DPdW9E2@d@#zF*_(G#>9WZ5o+*N00dZy1+gN+XICC)?&H@c!Sm! z*B^MN%7#8+e)bjBVIViQe{=R{4LIuuTBF67wdWit@JJsyd zHz@ctfbj|3UbTDRvCMq_^uH7P0|`$u0Xk+4|cJy^C3@;z(H1SBGxG$gx?#yxfA zkP$ri4FgVihP~1*9VI-;7H@q}Vt2FxqQEo!l>1rAwjq@rzJBfJ81XNeCIR6p55O>1 zVfDK`1GwFIuw>xEpLa5VjM3bTZjaM#0uGidH|XKhfy~#Vzna$HJ3qhDFF=hq>G6Bv z$6;GU&!7Lmhkt~~ecg1Rss3({ z@~wOLa=&m*iwJ>Y>}Lx8j=S+v`0+@xF=jQ9b#Lq4wf~Q3zxRrEZ8#P1MC~I!IzYB$ zLI62nuV{DBvCMfMCfcN~zSHB17b5KWjoagy+l^E4)c7vhQL5TA-?0*CGISrP<|80) z6aid}%d?SeR&hHyYyqD0F`W-oq%o!Q|qbigLUS-$jjg z3!qOKerV4Kca7|CNd!n2-$Ysc(s7Y{V%Isp@A+%K@I$$~HfuTp_+r%hk;{_6Xu-?l z{=wPBFTj5jKukZd5b+L;cXB;Szi++s;h)$Aetj1LXjv0%_M<5fpK?6>*zec{w%wpI zjUboRw~FZ0Y2Uw}X(8c--x`c*E1qNIn3+^Czw&=}M*gdKj_(K^1;|XLdb}^;+ot>f zCBr|E{vF<~HTBJ8cZ4r+kpS|;R(9a=A8ViZivaFfd8_Nxf9IG>3xxdsW#_~H7k50h z%q3VMwVs6XPtrM1ehhmC#E8Dd>YL$39&Zn{+x{u7IRHO})haZAS;eOig_9mgxw|82 zQzt-CS_6Vqzm~Imf#e^B4KwBdw(Zsxqxiw^!4qT}@vB7j{?H?SKes-2GGu?bjmauJs$M_(I@sWEEMn2V@CXDfIADsdc61vLxDQ*hX?KQrH@kYE8rGXbnmv+0OxN5QxmU z`Jufb%=tLNHwPV72Jr(3AX*&%X8D${kM#~8?2UWcEZ>u&`15cW`G`%xGjV3mz6h%?){Q+t-jz#iYb>--yP#ZTc)+PSmJ zZ||W7orxG_Ad7U`5A8wintH9U$+2$|Ne< z0S8v!i)Pixvv16(##H2k$-qvH8mgo*L{@>^i^r|%Q?RmSqkW(;C zV!tVr&WWNG*rda(=n_Jz29YdIN5^P|q@q2vefqfhISS;=t=LpMRp`_#&FBXobXBi2 zacCeCu!bq!JmJqF?INA$vIN&ys6`tT%3vu=aS&hsD=P)Zv{^gZlD|K^k=i8vTuCl2 zEed5#o6UMh9QHylz}wmyD>@)LG~;NAZW=)-NChOTI}cXx9PVo$X1LY#da6)BGTF_g zu4$=P-OwDBkS+)_=H_*3H{lyDE=LrQ+WW(;aeUP!c{lx>zz?(_{JeUobeDLuzC($- z4=bK~Y$?yM>co%Zda(H&KoszEGv&h5{t~2>!hRJ&Ua>w+_M#GHeG5<5r^bs%@*SiD z;Dc_A6wgjP3MW|IuE_<@-fBWjiHb@J<80f?M|`15&ztNeFSJ4&{KZ>>K>TM4G6qfH zUkp)IN0s^+C!kyQB?6}UuGpFP>rVBP#^?Om01G>>M>tg|BFUOOF%FS-=IG#oX6oi5 zMa3l@I@J?4nVQcWDZ`<7mX_nBygMDXB+81$YtC(se_o%Pf%DCW5h;L+@J<0UW(tbE z)&?VwCGmhrcO9h7Ew#*VH`i#jvZl8YlwxSB=P~9cm;S0C6CZ{MX{gdUSyC6&8 z=4FGec(Juf{NzhO3FaJQHw7_u=2mD*p(raXK#JP0v`+L$Uw3ZI=mgt-FD#o!fS8kC zAjdsK&9vByjytQSi5>QdGTc&nVp0`UZ7M;)OmRMl8MY*S$_LpOqh`#o`hxPXjjfsI zJ@&=vp|}ef(@vj?v#LDqGRvXXw_B-U4pbj80

    LKDZtR)_xFM&mS)W`t88TDQ%)F7fVk^c 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

    YM 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≧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�GZ*(RAkLQ=7v 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 s-UdznWaXZxe8tNm9kC8& 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%0A%9X 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%0Ad8&lwA0{gMGsNo>$BMt(t}Qr>x(wN57^Kybx(o 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 VkMI-V4}bl2O;Yx9>Lsne{|{+L5Pkpv From 54a6684b432ad97e720a61ebab4181839d2a041c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 16 Oct 2025 16:08:01 -0300 Subject: [PATCH 110/116] refactor(deferred): consolidate facilitator calls from the server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../src/schemes/deferred/evm/client.test.ts | 20 ++-- .../x402/src/schemes/deferred/evm/client.ts | 15 ++- .../src/schemes/deferred/evm/facilitator.ts | 4 +- .../schemes/deferred/evm/integration.test.ts | 14 +-- .../src/schemes/deferred/evm/server.test.ts | 95 +++++++++++++++---- .../x402/src/schemes/deferred/evm/server.ts | 25 ++--- .../x402/src/types/verify/schemes/deferred.ts | 5 +- .../packages/x402/src/verify/useDeferred.ts | 12 +-- 8 files changed, 123 insertions(+), 67 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts index 294aa8aa19..f4d26baeb1 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.test.ts @@ -715,7 +715,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getAccountData: mockGetEscrowAccountDetails, + getBuyerData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -740,7 +740,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getAccountData: mockGetEscrowAccountDetails, + getBuyerData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -760,7 +760,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getAccountData: mockGetEscrowAccountDetails, + getBuyerData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -802,7 +802,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getAccountData: mockGetEscrowAccountDetails, + getBuyerData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -829,7 +829,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getAccountData: mockGetEscrowAccountDetails, + getBuyerData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -853,7 +853,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getAccountData: mockGetEscrowAccountDetails, + getBuyerData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -873,7 +873,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getAccountData: mockGetEscrowAccountDetails, + getBuyerData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -894,7 +894,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getAccountData: mockGetEscrowAccountDetails, + getBuyerData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -930,7 +930,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getAccountData: mockGetEscrowAccountDetails, + getBuyerData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -951,7 +951,7 @@ describe("createPaymentExtraPayload", () => { }); vi.mocked(useDeferredFacilitator).mockReturnValue({ - getAccountData: mockGetEscrowAccountDetails, + getBuyerData: mockGetEscrowAccountDetails, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); diff --git a/typescript/packages/x402/src/schemes/deferred/evm/client.ts b/typescript/packages/x402/src/schemes/deferred/evm/client.ts index ca66de6ed7..017505ece1 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/client.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/client.ts @@ -280,33 +280,30 @@ export async function createPaymentExtraPayload( // Ensure the deposit is actually needed // This creates a client/buyer <> facilitator interaction but it's necessary to avoid having to trust the seller - const { getAccountData } = useDeferredFacilitator({ + const { getBuyerData } = useDeferredFacilitator({ url: extra.account.facilitator as `${string}://${string}`, }); - const accountDetails = await getAccountData( + const buyerData = await getBuyerData( buyer, paymentRequirements.payTo, asset, extra.voucher.escrow, getNetworkId(network), ); - if ("error" in accountDetails) { + if ("error" in buyerData) { return; } // Re-check balance using the data obtained from the facilitator - if ( - BigInt(accountDetails.balance) >= - BigInt(depositConfig.threshold) + BigInt(maxAmountRequired) - ) { + if (BigInt(buyerData.balance) >= BigInt(depositConfig.threshold) + BigInt(maxAmountRequired)) { return; } // Build ERC20 permit if needed let signedErc20Permit: DeferredEscrowDepositAuthorizationSignedPermit | undefined; - if (BigInt(accountDetails.assetAllowance) < BigInt(depositConfig.amount)) { + if (BigInt(buyerData.assetAllowance) < BigInt(depositConfig.amount)) { const erc20Permit = { - nonce: accountDetails.assetPermitNonce, + nonce: buyerData.assetPermitNonce, value: depositConfig.amount, domain: { name: depositConfig.assetDomain.name, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index b74c01216f..3a28286781 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -18,7 +18,7 @@ import { } from "../../../types/verify"; import { ErrorReasons } from "../../../types/verify/x402Specs"; import { - DeferredAccountDetailsResponse, + DeferredBuyerDataResponse, DeferredDepositWithAuthorizationResponse, DeferredErrorResponse, DeferredEscrowDepositAuthorization, @@ -574,7 +574,7 @@ export async function getAccountData< escrow: Address, chainId: number, voucherStore: VoucherStore, -): Promise { +): Promise { const outstandingVouchers = await voucherStore.getVouchers( { buyer, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts index bf6408d95d..136f120859 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts @@ -17,7 +17,7 @@ import { createPaymentHeader } from "../../../client"; vi.mock("../../../verify/useDeferred", () => ({ useDeferredFacilitator: vi.fn().mockReturnValue({ - getAccountData: vi.fn().mockResolvedValue({ + getBuyerData: vi.fn().mockResolvedValue({ balance: "10000000", assetAllowance: "1000000", assetPermitNonce: "0", @@ -551,15 +551,15 @@ describe("Deferred Payment Integration Tests", () => { }, } as DeferredPaymentRequirements; - // Mock facilitator getAccountData call + // Mock facilitator getBuyerData call const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); - const mockGetAccountData = vi.fn().mockResolvedValue({ + const mockGetBuyerData = vi.fn().mockResolvedValue({ balance: "500", // Confirm low balance assetAllowance: "0", assetPermitNonce: "0", }); (useDeferredFacilitator as ReturnType).mockReturnValue({ - getAccountData: mockGetAccountData, + getBuyerData: mockGetBuyerData, }); // * Step 2: Client automatically generates deposit authorization using createPaymentExtraPayload @@ -582,7 +582,7 @@ describe("Deferred Payment Integration Tests", () => { expect(extraPayload?.depositAuthorization).toBeDefined(); // Verify facilitator was called to check balance - expect(mockGetAccountData).toHaveBeenCalledWith( + expect(mockGetBuyerData).toHaveBeenCalledWith( buyerAddress, sellerAddress, assetAddress, @@ -781,13 +781,13 @@ describe("Deferred Payment Integration Tests", () => { // Mock facilitator call const { useDeferredFacilitator } = await import("../../../verify/useDeferred"); - const mockGetAccountData = vi.fn().mockResolvedValue({ + const mockGetBuyerData = vi.fn().mockResolvedValue({ balance: "500", assetAllowance: "2000000", assetPermitNonce: "0", }); (useDeferredFacilitator as ReturnType).mockReturnValue({ - getAccountData: mockGetAccountData, + getBuyerData: mockGetBuyerData, }); // * Step 2: Generate deposit authorization without permit diff --git a/typescript/packages/x402/src/schemes/deferred/evm/server.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/server.test.ts index d0c4cbdb73..86330e7770 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/server.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/server.test.ts @@ -48,16 +48,16 @@ describe("getPaymentRequirementsExtra", () => { }; const mockGetAvailableVoucher = vi.fn(); - const mockGetEscrowAccountDetails = vi.fn(); + const mockGetBuyerData = vi.fn(); beforeEach(() => { vi.clearAllMocks(); vi.mocked(idModule.generateVoucherId).mockReturnValue(mockVoucherId); vi.mocked(useDeferredModule.useDeferredFacilitator).mockReturnValue({ - getEscrowAccountDetails: mockGetEscrowAccountDetails, + getBuyerData: mockGetBuyerData, } as unknown as ReturnType); - // Mock getEscrowAccountDetails to return an error by default (so it doesn't add account info) - mockGetEscrowAccountDetails.mockResolvedValue({ error: "not available" }); + // Mock getBuyerData to return an error by default (so it doesn't add account info) + mockGetBuyerData.mockResolvedValue({ error: "not available" }); }); describe("when no headers are provided", () => { @@ -88,6 +88,11 @@ describe("getPaymentRequirementsExtra", () => { describe("when only X-BUYER header is provided", () => { it("should return aggregation extra when previous voucher exists", async () => { + mockGetBuyerData.mockResolvedValue({ + balance: "10000000", + assetAllowance: "1000000", + assetPermitNonce: "0", + }); mockGetAvailableVoucher.mockResolvedValue(mockVoucher); const result = await getPaymentRequirementsExtra( @@ -103,6 +108,12 @@ describe("getPaymentRequirementsExtra", () => { expect(result).toEqual({ type: "aggregation", + account: { + balance: "10000000", + assetAllowance: "1000000", + assetPermitNonce: "0", + facilitator: "https://facilitator.x402.io", + }, signature: mockSignature, voucher: mockVoucher, }); @@ -112,6 +123,11 @@ describe("getPaymentRequirementsExtra", () => { }); it("should return new voucher extra when no previous voucher exists", async () => { + mockGetBuyerData.mockResolvedValue({ + balance: "10000000", + assetAllowance: "1000000", + assetPermitNonce: "0", + }); mockGetAvailableVoucher.mockResolvedValue(null); const result = await getPaymentRequirementsExtra( @@ -127,6 +143,12 @@ describe("getPaymentRequirementsExtra", () => { expect(result).toEqual({ type: "new", + account: { + balance: "10000000", + assetAllowance: "1000000", + assetPermitNonce: "0", + facilitator: "https://facilitator.x402.io", + }, voucher: { id: mockVoucherId, escrow: mockEscrow, @@ -151,6 +173,11 @@ describe("getPaymentRequirementsExtra", () => { }, }); + mockGetBuyerData.mockResolvedValue({ + balance: "10000000", + assetAllowance: "1000000", + assetPermitNonce: "0", + }); mockGetAvailableVoucher.mockResolvedValue(mockVoucher); const result = await getPaymentRequirementsExtra( @@ -166,6 +193,12 @@ describe("getPaymentRequirementsExtra", () => { expect(result).toEqual({ type: "aggregation", + account: { + balance: "10000000", + assetAllowance: "1000000", + assetPermitNonce: "0", + facilitator: "https://facilitator.x402.io", + }, signature: mockSignature, voucher: mockVoucher, }); @@ -218,6 +251,11 @@ describe("getPaymentRequirementsExtra", () => { }, }); + mockGetBuyerData.mockResolvedValue({ + balance: "10000000", + assetAllowance: "1000000", + assetPermitNonce: "0", + }); mockGetAvailableVoucher.mockResolvedValue(null); const result = await getPaymentRequirementsExtra( @@ -233,6 +271,12 @@ describe("getPaymentRequirementsExtra", () => { expect(result).toEqual({ type: "new", + account: { + balance: "10000000", + assetAllowance: "1000000", + assetPermitNonce: "0", + facilitator: "https://facilitator.x402.io", + }, voucher: { id: mockVoucherId, escrow: mockEscrow, @@ -260,6 +304,12 @@ describe("getPaymentRequirementsExtra", () => { }, }); + mockGetBuyerData.mockResolvedValue({ + balance: "10000000", + assetAllowance: "1000000", + assetPermitNonce: "0", + }); + const voucherResponse: DeferredEvmPayloadSignedVoucher = { ...mockVoucher, buyer: differentBuyer, @@ -279,6 +329,12 @@ describe("getPaymentRequirementsExtra", () => { expect(result).toEqual({ type: "aggregation", + account: { + balance: "10000000", + assetAllowance: "1000000", + assetPermitNonce: "0", + facilitator: "https://facilitator.x402.io", + }, signature: mockSignature, voucher: { ...mockVoucher, @@ -297,18 +353,25 @@ describe("getPaymentRequirementsExtra", () => { it("should handle getAvailableVoucher throwing an error", async () => { mockGetAvailableVoucher.mockRejectedValue(new Error("Database error")); - await expect( - getPaymentRequirementsExtra( - undefined, - mockBuyer, - mockSeller, - mockEscrow, - mockAsset, - mockChainId, - { url: "https://facilitator.x402.io" }, - mockGetAvailableVoucher, - ), - ).rejects.toThrow("Database error"); + // When getAvailableVoucher fails, the function catches the error and returns a new voucher + const result = await getPaymentRequirementsExtra( + undefined, + mockBuyer, + mockSeller, + mockEscrow, + mockAsset, + mockChainId, + { url: "https://facilitator.x402.io" }, + mockGetAvailableVoucher, + ); + + expect(result).toEqual({ + type: "new", + voucher: { + id: mockVoucherId, + escrow: mockEscrow, + }, + }); }); it("should handle decodePayment throwing an error", async () => { diff --git a/typescript/packages/x402/src/schemes/deferred/evm/server.ts b/typescript/packages/x402/src/schemes/deferred/evm/server.ts index aa50e2ba05..35c52200f3 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/server.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/server.ts @@ -35,17 +35,7 @@ export async function getPaymentRequirementsExtra( seller: string, ) => Promise, ): Promise { - const { getAccountData, getAvailableVoucher } = useDeferredFacilitator(facilitator); - const getAvailableVoucherFacilitator = async (buyer: string, seller: string) => { - const result = await getAvailableVoucher(buyer, seller); - if ("error" in result) { - if (result.error === "voucher_not_found") { - return null; - } - throw new Error(result.error); - } - return result; - }; + const { getBuyerData } = useDeferredFacilitator(facilitator); let buyer: Address; const newVoucherExtra: PaymentRequirementsExtra = { @@ -73,16 +63,23 @@ export async function getPaymentRequirementsExtra( buyer = xBuyerHeader!; // This is safe due to the previous early return } - // Retrieve account details from facilitator + // Retrieve buyer data from facilitator and/or local voucher store let balance = ""; let assetAllowance = ""; let assetPermitNonce = ""; let success = false; + let previousVoucher: DeferredEvmPayloadSignedVoucher | null = null; try { - const response = await getAccountData(buyer, seller, asset, escrow, chainId); + const response = await getBuyerData(buyer, seller, asset, escrow, chainId); if (!("error" in response)) { success = true; ({ balance, assetAllowance, assetPermitNonce } = response); + + if (getAvailableVoucherLocal == undefined) { + previousVoucher = response.voucher ?? null; + } else { + previousVoucher = await getAvailableVoucherLocal(buyer, seller); + } } } catch (error) { console.error(error); @@ -95,8 +92,6 @@ export async function getPaymentRequirementsExtra( facilitator: facilitator.url, }; - const getAvailableVoucherFn = getAvailableVoucherLocal ?? getAvailableVoucherFacilitator; - const previousVoucher = await getAvailableVoucherFn(buyer, seller); if (previousVoucher) { return { type: "aggregation" as const, diff --git a/typescript/packages/x402/src/types/verify/schemes/deferred.ts b/typescript/packages/x402/src/types/verify/schemes/deferred.ts index 893a2d2d7f..89aea39bc3 100644 --- a/typescript/packages/x402/src/types/verify/schemes/deferred.ts +++ b/typescript/packages/x402/src/types/verify/schemes/deferred.ts @@ -336,9 +336,10 @@ export type DeferredFlushWithAuthorizationResponse = z.infer< >; // x402DeferredAccountDetailsResponse -export const DeferredAccountDetailsResponseSchema = z.object({ +export const DeferredBuyerDataResponseSchema = z.object({ balance: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), assetAllowance: z.string().refine(isInteger).refine(hasMaxLength(EvmMaxAtomicUnits)), assetPermitNonce: z.string().refine(isBigInt), + voucher: DeferredEvmPayloadSignedVoucherSchema.optional(), }); -export type DeferredAccountDetailsResponse = z.infer; +export type DeferredBuyerDataResponse = z.infer; diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index 8898de1293..eac72b0479 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -1,6 +1,6 @@ import { toJsonSafe } from "../shared/json"; import { - DeferredAccountDetailsResponse, + DeferredBuyerDataResponse, DeferredErrorResponse, DeferredEscrowFlushAuthorizationSigned, DeferredFlushWithAuthorizationResponse, @@ -293,14 +293,14 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { * @param chainId - The chain ID * @returns The balance of the escrow account */ - async function getAccountData( + async function getBuyerData( buyer: string, seller: string, asset: string, escrow: string, chainId: number, - ): Promise { - const response = await fetch(`${facilitator.url}/deferred/buyers/${buyer}/account`, { + ): Promise { + const response = await fetch(`${facilitator.url}/deferred/buyers/${buyer}`, { method: "GET", headers: { "Content-Type": "application/json", @@ -308,7 +308,7 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { body: JSON.stringify({ seller, asset, escrow, chainId }), }); const responseJson = (await response.json()) as - | DeferredAccountDetailsResponse + | DeferredBuyerDataResponse | DeferredErrorResponse; if ("error" in responseJson) { throw new Error(responseJson.error); @@ -359,7 +359,7 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { verifyVoucher, settleVoucher, getVoucherCollections, - getAccountData, + getBuyerData, flushEscrow, }; } From bde440b5ec5969c464fbb494699415057f6b5dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 16 Oct 2025 16:29:03 -0300 Subject: [PATCH 111/116] chore(deferred): remove x402-fetch incomplete implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-fetch/README.md | 89 --------- .../packages/x402-fetch/src/index.test.ts | 173 +----------------- typescript/packages/x402-fetch/src/index.ts | 142 +------------- 3 files changed, 12 insertions(+), 392 deletions(-) diff --git a/typescript/packages/x402-fetch/README.md b/typescript/packages/x402-fetch/README.md index c84f9dc847..5b3bfd3886 100644 --- a/typescript/packages/x402-fetch/README.md +++ b/typescript/packages/x402-fetch/README.md @@ -10,8 +10,6 @@ npm install x402-fetch ## Quick Start -### Exact Scheme - ```typescript import { createWalletClient, http } from "viem"; import { privateKeyToAccount } from "viem/accounts"; @@ -37,33 +35,6 @@ const response = await fetchWithPay("https://api.example.com/paid-endpoint", { const data = await response.json(); ``` -### Deferred Scheme - -```typescript -import { createWalletClient, http } from "viem"; -import { privateKeyToAccount } from "viem/accounts"; -import { wrapFetchWithPayment } from "x402-fetch"; -import { baseSepolia } from "viem/chains"; - -// Create a wallet client -const account = privateKeyToAccount("0xYourPrivateKey"); -const client = createWalletClient({ - account, - transport: http(), - chain: baseSepolia, -}); - -// Wrap the fetch function with deferred payment handling -const fetchWithDeferredPay = wrapFetchWithDeferredPayment(fetch, client); - -// Make a request that may require payment -const response = await fetchWithDeferredPay("https://api.example.com/paid-endpoint", { - method: "GET", -}); - -const data = await response.json(); -``` - ## API ### `wrapFetchWithPayment(fetch, walletClient, maxValue?, paymentRequirementsSelector?)` @@ -80,7 +51,6 @@ Wraps the native fetch API to handle 402 Payment Required responses automaticall #### Returns A wrapped fetch function that automatically handles 402 responses by: - 1. Making the initial request 2. If a 402 response is received, parsing the payment requirements 3. Verifying the payment amount is within the allowed maximum @@ -122,62 +92,3 @@ fetchWithPay(API_URL, { }); ``` -### `wrapFetchWithDeferredPayment(fetch, walletClient, maxRequestValue?, paymentRequirementsSelector?)` - -Wraps the native fetch API to handle 402 Deferred Payment Required responses automatically. - -#### When to use - -The `wrapFetchWithDeferredPayment` method should be used if the facilitator/seller being called is configured to allow for deferred/aggregated payments using a configured escrow account. The biggest difference is that the `wrapFetchWithPayment` method, if a 402 response is returned, will process the payment for each request. The `wrapFetchWithDeferredPayment` and `deferred` payment schemes allow the buyer (the user of this library) to make _multiple_ requests where the amount is aggregated and then paid off with **one** onchain transaciton covering all requests on a given voucher. - -#### Parameters - -- `fetch`: The fetch function to wrap (typically `globalThis.fetch`) -- `walletClient`: The wallet client used to sign payment messages (must implement the x402 wallet interface) -- `maxRequestValue`: Optional maximum allowed payment amount, for any given request, in base units (defaults to 0.1 USDC) -- `paymentRequirementsSelector`: Optional function to select payment requirements from the response (defaults to `selectPaymentRequirements`) - -#### Returns - -A wrapped fetch function that automatically handles 402 deferred payment responses by: - -1. Making the initial request -2. If a 402 response is received, parsing the payment requirements -3. Verifying the payment amount is within the allowed maximum -4. Creating a payment header using the provided wallet client -5. Retrying the request with the payment header - -## Example - -```typescript -import { config } from "dotenv"; -import { createWalletClient, http } from "viem"; -import { privateKeyToAccount } from "viem/accounts"; -import { wrapFetchWithPayment } from "x402-fetch"; -import { baseSepolia } from "viem/chains"; - -config(); - -const { PRIVATE_KEY, API_URL } = process.env; - -const account = privateKeyToAccount(PRIVATE_KEY as `0x${string}`); -const client = createWalletClient({ - account, - transport: http(), - chain: baseSepolia, -}); - -const fetchWithDeferredPay = wrapFetchWithDeferredPayment(fetch, client); - -// Make a request to a paid API endpoint -fetchWithDeferredPay(API_URL, { - method: "GET", -}) - .then(async response => { - const data = await response.json(); - console.log(data); - }) - .catch(error => { - console.error(error); - }); -``` diff --git a/typescript/packages/x402-fetch/src/index.test.ts b/typescript/packages/x402-fetch/src/index.test.ts index 1eb0f600c8..333b89680d 100644 --- a/typescript/packages/x402-fetch/src/index.test.ts +++ b/typescript/packages/x402-fetch/src/index.test.ts @@ -1,6 +1,6 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; -import { DeferredPaymentRequirements, evm, PaymentRequirements } from "x402/types"; -import { wrapFetchWithPayment, wrapFetchWithDeferredPayment } from "./index"; +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { wrapFetchWithPayment } from "./index"; +import { evm, PaymentRequirements } from "x402/types"; vi.mock("x402/client", () => ({ createPaymentHeader: vi.fn(), @@ -167,170 +167,3 @@ describe("fetchWithPayment()", () => { ).rejects.toBe(paymentError); }); }); - -describe("fetchWithDeferredPayment()", () => { - let mockFetch: ReturnType; - let mockWalletClient: typeof evm.SignerWallet; - let wrappedDeferredFetch: ReturnType; - const escrowAddress = "0xffffff12345678901234567890123456789fffff"; - const voucherId = "0x7a3e9b10e8a59f9b4e87219b7e5f3e69ac1b7e4625b5de38b1ff8d470ab7f4f1"; - const validPaymentRequirements: Array = [ - { - scheme: "deferred", - network: "base-sepolia", - maxAmountRequired: "100000", // 0.1 USDC in base units - resource: "https://api.example.com/resource", - description: "Test payment", - mimeType: "application/json", - payTo: "0x1234567890123456789012345678901234567890", - maxTimeoutSeconds: 300, - asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", // USDC on base-sepolia - extra: { - type: "new", - voucher: { - id: voucherId, - escrow: escrowAddress, - }, - }, - }, - ]; - - const createResponse = (status: number, data?: unknown): Response => { - return new Response(JSON.stringify(data), { - status, - statusText: status === 402 ? "Payment Required" : "Not Found", - headers: new Headers(), - }); - }; - - beforeEach(async () => { - vi.resetAllMocks(); - - mockFetch = vi.fn(); - - mockWalletClient = { - signMessage: vi.fn(), - } as unknown as typeof evm.SignerWallet; - - // Mock payment requirements selector - const { selectPaymentRequirements } = await import("x402/client"); - (selectPaymentRequirements as ReturnType).mockImplementation( - (requirements, _) => requirements[0], - ); - - wrappedDeferredFetch = wrapFetchWithDeferredPayment(mockFetch, mockWalletClient); - }); - - it("should return the original response for non-402 status codes", async () => { - const successResponse = createResponse(200, { data: "success" }); - mockFetch.mockResolvedValue(successResponse); - - const result = await wrappedDeferredFetch("https://api.example.com"); - - expect(result).toBe(successResponse); - expect(mockFetch).toHaveBeenCalledWith("https://api.example.com", undefined); - }); - - it("should handle 402 errors and retry with payment header", async () => { - const paymentHeader = "payment-header-value"; - const successResponse = createResponse(200, { data: "success" }); - - const { createPaymentHeader, selectPaymentRequirements } = await import("x402/client"); - (createPaymentHeader as ReturnType).mockResolvedValue(paymentHeader); - (selectPaymentRequirements as ReturnType).mockImplementation( - (requirements, _) => requirements[0], - ); - mockFetch - .mockResolvedValueOnce( - createResponse(402, { accepts: validPaymentRequirements, x402Version: 1 }), - ) - .mockResolvedValueOnce(successResponse); - - const result = await wrappedDeferredFetch("https://api.example.com", { - method: "GET", - headers: { "Content-Type": "application/json" }, - } as RequestInitWithRetry); - - expect(result).toBe(successResponse); - expect(selectPaymentRequirements).toHaveBeenCalledWith( - validPaymentRequirements, - undefined, - "deferred", - ); - expect(createPaymentHeader).toHaveBeenCalledWith( - mockWalletClient, - 1, - validPaymentRequirements[0], - ); - expect(mockFetch).toHaveBeenCalledTimes(2); - expect(mockFetch).toHaveBeenLastCalledWith("https://api.example.com", { - method: "GET", - headers: { - "Content-Type": "application/json", - "X-PAYMENT": paymentHeader, - "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", - }, - __is402Retry: true, - } as RequestInitWithRetry); - }); - - it("should not retry if already retried", async () => { - const errorResponse = createResponse(402, { - accepts: validPaymentRequirements, - x402Version: 1, - }); - mockFetch.mockResolvedValue(errorResponse); - - await expect( - wrappedDeferredFetch("https://api.example.com", { - __is402Retry: true, - } as RequestInitWithRetry), - ).rejects.toThrow("Payment already attempted"); - }); - - it("should reject if missing request config", async () => { - const errorResponse = createResponse(402, { - accepts: validPaymentRequirements, - x402Version: 1, - }); - mockFetch.mockResolvedValue(errorResponse); - - await expect(wrappedDeferredFetch("https://api.example.com")).rejects.toThrow( - "Missing fetch request configuration", - ); - }); - - it("should reject if payment amount exceeds maximum transaction amount", async () => { - const errorResponse = createResponse(402, { - accepts: [ - { - ...validPaymentRequirements[0], - maxAmountRequired: "200000", // 0.2 USDC, which exceeds our default max of 0.1 USDC - }, - ], - x402Version: 1, - }); - mockFetch.mockResolvedValue(errorResponse); - - await expect( - wrappedDeferredFetch("https://api.example.com", { - method: "GET", - } as RequestInitWithRetry), - ).rejects.toThrow("Payment amount exceeds maximum request allowed amount"); - }); - - it("should reject if payment header creation fails", async () => { - const paymentError = new Error("Payment failed"); - const { createPaymentHeader } = await import("x402/client"); - (createPaymentHeader as ReturnType).mockRejectedValue(paymentError); - mockFetch.mockResolvedValue( - createResponse(402, { accepts: validPaymentRequirements, x402Version: 1 }), - ); - - await expect( - wrappedDeferredFetch("https://api.example.com", { - method: "GET", - } as RequestInitWithRetry), - ).rejects.toBe(paymentError); - }); -}); diff --git a/typescript/packages/x402-fetch/src/index.ts b/typescript/packages/x402-fetch/src/index.ts index 174e2bb6f6..16c3b056ef 100644 --- a/typescript/packages/x402-fetch/src/index.ts +++ b/typescript/packages/x402-fetch/src/index.ts @@ -1,23 +1,18 @@ -import { Client, LocalAccount } from "viem"; -import { - createPaymentHeader, - PaymentRequirementsSelector, - selectPaymentRequirements, -} from "x402/client"; import { ChainIdToNetwork, - DeferredPaymentRequirementsSchema, - DEFERRRED_SCHEME, - evm, - EXACT_SCHEME, PaymentRequirementsSchema, - Wallet, - Network, + Signer, + evm, MultiNetworkSigner, isMultiNetworkSigner, isSvmSignerWallet, - Signer, + Network, } from "x402/types"; +import { + createPaymentHeader, + PaymentRequirementsSelector, + selectPaymentRequirements, +} from "x402/client"; /** * Enables the payment of APIs using the x402 payment protocol. @@ -80,7 +75,7 @@ export function wrapFetchWithPayment( const selectedPaymentRequirements = paymentRequirementsSelector( parsedPaymentRequirements, network, - EXACT_SCHEME, + "exact", ); if (BigInt(selectedPaymentRequirements.maxAmountRequired) > maxValue) { @@ -116,125 +111,6 @@ export function wrapFetchWithPayment( }; } -/** - * Enables the payment of APIs using the x402 deferred payment protocol. - * - * This function wraps the native fetch API to automatically handle 402 Payment Required responses - * by creating and sending a payment header. It will: - * 1. Make the initial request - * 2. If a 402 response is received, parse the payment requirements - * 3. Verify the payment amount is within the allowed maximum (maxTransactionValue param) - * 5. Create a payment header using the provided wallet client - * 6. Retry the request with the payment header - * - * When to use: - * In the instance that the paid api endpoint being requested supports the x402 deferred scheme. - * - * @param fetch - The fetch function to wrap (typically globalThis.fetch) - * @param walletClient - The wallet client used to sign payment messages - * @param maxRequestValue - The maximum allowed payment amount in base units (defaults to 0.1 USDC) for any given request - * @param paymentRequirementsSelector - A function that selects the payment requirements from the response - * @returns A wrapped fetch function that handles 402 responses automatically - * - * @example Default amounts - * ```typescript - * const wallet = new SignerWallet(...); - * const fetchWithDeferredPay = wrapFetchWithDeferredPayment(fetch, wallet); - * - * // Make a request that may require payment - * const response = await fetchWithDeferredPay('https://api.example.com/paid-endpoint'); - * ``` - * - * @example Set max aggregate and transactional amounts - * ```typescript - * const wallet = new SignerWallet(...); - * const fetchWithDeferredPay = wrapFetchWithDeferredPayment(fetch, wallet, BigInt(0.2 * 10 ** 6)); - * - * // Make a request that may require payment - * const response = await fetchWithDeferredPay('https://api.example.com/paid-endpoint'); - * ``` - * - * @throws {Error} If the transaction payment amount exceeds the transaction maximum allowed value - * @throws {Error} If the request configuration is missing - * @throws {Error} If a payment has already been attempted for this request - * @throws {Error} If there's an error creating the payment header - */ -export function wrapFetchWithDeferredPayment( - fetch: typeof globalThis.fetch, - walletClient: Wallet, - maxRequestValue: bigint = BigInt(0.1 * 10 ** 6), // Default to 0.10 USDC - paymentRequirementsSelector: PaymentRequirementsSelector = selectPaymentRequirements, -) { - return async (input: RequestInfo, init?: RequestInit) => { - // Add header to the initial request to identify the buyer - const buyer = - (walletClient as LocalAccount).address || (walletClient as Client).account?.address; - if (buyer) { - init = { - ...init, - headers: { - ...(init?.headers || {}), - "X-PAYMENT-BUYER": buyer, - }, - }; - } - - const response = await fetch(input, init); - - if (response.status !== 402) { - return response; - } - - const { x402Version, accepts } = (await response.json()) as { - x402Version: number; - accepts: unknown[]; - }; - const parsedPaymentRequirements = accepts.map(x => PaymentRequirementsSchema.parse(x)); - - const chainId = evm.isSignerWallet(walletClient) ? walletClient.chain?.id : undefined; - const selectedPaymentRequirements = paymentRequirementsSelector( - parsedPaymentRequirements, - chainId ? ChainIdToNetwork[chainId] : undefined, - DEFERRRED_SCHEME, - ); - const selectedDeferredPaymentRequirements = DeferredPaymentRequirementsSchema.parse( - selectedPaymentRequirements, - ); - - const transactionAmount = BigInt(selectedDeferredPaymentRequirements.maxAmountRequired); - if (transactionAmount > maxRequestValue) { - throw new Error("Payment amount exceeds maximum request allowed amount"); - } - - const paymentHeader = await createPaymentHeader( - walletClient, - x402Version, - selectedDeferredPaymentRequirements, - ); - - if (!init) { - throw new Error("Missing fetch request configuration"); - } - - if ((init as { __is402Retry?: boolean }).__is402Retry) { - throw new Error("Payment already attempted"); - } - - const newInit = { - ...init, - headers: { - ...(init.headers || {}), - "X-PAYMENT": paymentHeader, - "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", - }, - __is402Retry: true, - }; - - const paymentHeaderSignedResponse = await fetch(input, newInit); - return paymentHeaderSignedResponse; - }; -} - export { decodeXPaymentResponse } from "x402/shared"; export { createSigner, type Signer, type MultiNetworkSigner } from "x402/types"; export type { Hex } from "viem"; From d33da389025c3d5b6eb66874e1a9e8aaf53c8296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 16 Oct 2025 17:15:57 -0300 Subject: [PATCH 112/116] test: fix x402-axios test, adjust expected object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- typescript/packages/x402-axios/src/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript/packages/x402-axios/src/index.test.ts b/typescript/packages/x402-axios/src/index.test.ts index 89ae843a51..adbc6e91e3 100644 --- a/typescript/packages/x402-axios/src/index.test.ts +++ b/typescript/packages/x402-axios/src/index.test.ts @@ -367,7 +367,7 @@ describe("withDeferredPaymentInterceptor", () => { mockWalletClient, 1, validPaymentRequirements[0], - extraPayload, + { extraPayload }, ); const actualCall = (mockAxiosClient.request as ReturnType).mock.calls[0][0]; From 20a365f46108e4690c5c76681994379ca0f178aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 16 Oct 2025 17:59:12 -0300 Subject: [PATCH 113/116] fix(deferred): use latest contract, no body on get requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- examples/typescript/facilitator/index.ts | 68 +++++++++++---- .../typescript/servers/express/.env-local | 2 +- solidity/deferred-escrow/addresses.json | 2 +- .../scheme_deferred_evm_facilitator.md | 17 ++-- .../x402/src/verify/useDeferred.test.ts | 82 +++++++++++++++++++ .../packages/x402/src/verify/useDeferred.ts | 10 ++- 6 files changed, 154 insertions(+), 27 deletions(-) diff --git a/examples/typescript/facilitator/index.ts b/examples/typescript/facilitator/index.ts index 09742a0867..dee48b4c8a 100644 --- a/examples/typescript/facilitator/index.ts +++ b/examples/typescript/facilitator/index.ts @@ -21,12 +21,14 @@ import { type X402Config, } from "x402/types"; import { deferred } from "x402/schemes"; +import { getNetworkName } from "x402/shared"; config(); const EVM_PRIVATE_KEY = process.env.EVM_PRIVATE_KEY || ""; const SVM_PRIVATE_KEY = process.env.SVM_PRIVATE_KEY || ""; const SVM_RPC_URL = process.env.SVM_RPC_URL || ""; +const PORT = process.env.PORT || 3000; if (!EVM_PRIVATE_KEY && !SVM_PRIVATE_KEY) { console.error("Missing required environment variables"); @@ -186,17 +188,33 @@ app.get("/deferred/vouchers/:id", async (req: Request, res: Response) => { } }); -// GET /deferred/vouchers/available/:buyer/:seller -app.get("/deferred/vouchers/available/:buyer/:seller", async (req: Request, res: Response) => { +// GET /deferred/buyers/:buyer +app.get("/deferred/buyers/:buyer", async (req: Request, res: Response) => { try { - const { buyer, seller } = req.params; - const voucher = await voucherStore.getAvailableVoucher(buyer, seller); + const { buyer } = req.params; + const { seller, asset, escrow, chainId } = req.query; + + const network = getNetworkName(parseInt(chainId as string, 10)); + const client = evm.createConnectedClient(network); + const response = await deferred.evm.getAccountData( + client, + buyer as `0x${string}`, + seller as `0x${string}`, + asset as `0x${string}`, + escrow as `0x${string}`, + parseInt(chainId as string, 10), + voucherStore, + ); - if (!voucher) { - return res.status(404).json({ error: "No vouchers available for this buyer-seller pair" }); + if ("error" in response) { + return res.status(404).json({ + error: response.error, + }); } - res.json(voucher); + const voucher = await voucherStore.getAvailableVoucher(buyer, seller as `0x${string}`); + + res.json({ ...response, voucher: voucher ?? undefined }); } catch (error) { console.error("error", error); res.status(400).json({ error: "Invalid request" }); @@ -216,9 +234,31 @@ app.post("/deferred/vouchers", async (req: Request, res: Response) => { return res.status(400).json(verifyResponse); } - // Extract and store the voucher - const { signature, voucher } = DeferredEvmPayloadSchema.parse(paymentPayload.payload); + // Extract voucher + const { depositAuthorization, signature, voucher } = DeferredEvmPayloadSchema.parse( + paymentPayload.payload, + ); const signedVoucher = { ...voucher, signature }; + + // Process deposit authorization + if (depositAuthorization) { + const network = getNetworkName(voucher.chainId); + const signer = evm.createSigner(network, EVM_PRIVATE_KEY as `0x${string}`); + const depositResponse = await deferred.evm.depositWithAuthorization( + signer, + signedVoucher, + depositAuthorization, + false, + ); // Skip reverification - already verified in verify() call above + if (!depositResponse.success) { + return res.status(400).json({ + error: depositResponse.errorReason ?? "Unknown deposit authorization error", + details: { depositAuthorization }, + }); + } + } + + // Store the voucher const result = await voucherStore.storeVoucher(signedVoucher); if (!result.success) { @@ -277,13 +317,11 @@ app.post("/deferred/vouchers/:id/:nonce/settle", async (req: Request, res: Respo } }); -app.listen(process.env.PORT || 3000, () => { - console.log(`Server listening at http://localhost:${process.env.PORT || 3000}`); +app.listen(PORT, () => { + console.log(`Server listening at http://localhost:${PORT}`); + console.log(`For deferred voucher history: GET http://localhost:${PORT}/deferred/vouchers/:id`); console.log( - `For deferred voucher history: GET http://localhost:${process.env.PORT || 3000}/deferred/vouchers/:id`, - ); - console.log( - `To settle a deferred voucher: POST http://localhost:${process.env.PORT || 3000}/deferred/vouchers/:id/:nonce/settle`, + `To settle a deferred voucher: POST http://localhost:${PORT}/deferred/vouchers/:id/:nonce/settle`, ); }); diff --git a/examples/typescript/servers/express/.env-local b/examples/typescript/servers/express/.env-local index f216d4d803..6a9f41aa9f 100644 --- a/examples/typescript/servers/express/.env-local +++ b/examples/typescript/servers/express/.env-local @@ -1,7 +1,7 @@ FACILITATOR_URL=https://x402.org/facilitator NETWORK=base-sepolia ADDRESS= -DEFERRED_ESCROW=0xfda9048c2e6ba55874003a9595c7f90c2d6af1e6 +DEFERRED_ESCROW=0x246fece47fa8c4a1a58348ad576685ef2bdb06c8 # required if using the Base mainnet facilitator CDP_API_KEY_ID="Coinbase Developer Platform Key" diff --git a/solidity/deferred-escrow/addresses.json b/solidity/deferred-escrow/addresses.json index 75778a8d15..248494edd7 100644 --- a/solidity/deferred-escrow/addresses.json +++ b/solidity/deferred-escrow/addresses.json @@ -1,5 +1,5 @@ { "84532": { - "deferredPaymentEscrow": "0xfda9048c2e6ba55874003a9595c7f90c2d6af1e6" + "deferredPaymentEscrow": "0x246fece47fa8c4a1a58348ad576685ef2bdb06c8" } } \ No newline at end of file diff --git a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md index 07e8ea5acd..808fc8145a 100644 --- a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md +++ b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md @@ -17,14 +17,15 @@ As for write endpoints, they do not require traditional authentication but inste Retrieves buyer data for a specific buyer, including escrow account balance, asset allowance, permit nonce, and the latest available voucher for a particular seller and asset. -**Request Body:** -```json -{ - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532 -} +**Query Parameters:** +- `seller` (required): Seller address (e.g., "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D") +- `asset` (required): Asset address (e.g., "0x081827b8c3aa05287b5aa2bc3051fbe638f33152") +- `escrow` (required): Escrow address (e.g., "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27") +- `chainId` (required): Chain ID (e.g., 84532) + +**Example Request:** +``` +GET /buyers/0x209693Bc6afc0C5328bA36FaF03C514EF312287C?seller=0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D&asset=0x081827b8c3aa05287b5aa2bc3051fbe638f33152&escrow=0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27&chainId=84532 ``` **Response (200 OK):** diff --git a/typescript/packages/x402/src/verify/useDeferred.test.ts b/typescript/packages/x402/src/verify/useDeferred.test.ts index 50d1ed46a1..23f1383d20 100644 --- a/typescript/packages/x402/src/verify/useDeferred.test.ts +++ b/typescript/packages/x402/src/verify/useDeferred.test.ts @@ -917,6 +917,88 @@ describe("useDeferredFacilitator", () => { }); }); + describe("getBuyerData", () => { + it("should fetch buyer data successfully with query parameters", async () => { + const mockResponse = { + balance: "10000000", + assetAllowance: "5000000", + assetPermitNonce: "3", + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + const result = await facilitator.getBuyerData( + buyerAddress, + sellerAddress, + assetAddress, + escrowAddress, + 84532, + ); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${DEFAULT_FACILITATOR_URL}/deferred/buyers/${buyerAddress}?seller=${sellerAddress}&asset=${assetAddress}&escrow=${escrowAddress}&chainId=84532`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }, + ); + }); + + it("should throw error when response contains error field", async () => { + const mockErrorResponse = { + error: "Buyer data not found", + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockErrorResponse), + }); + + const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); + + await expect( + facilitator.getBuyerData(buyerAddress, sellerAddress, assetAddress, escrowAddress, 84532), + ).rejects.toThrow("Buyer data not found"); + }); + + it("should use custom facilitator URL", async () => { + const mockResponse = { + balance: "10000000", + assetAllowance: "5000000", + assetPermitNonce: "3", + }; + + mockFetch.mockResolvedValueOnce({ + status: 200, + json: () => Promise.resolve(mockResponse), + }); + + const facilitator = useDeferredFacilitator({ url: customFacilitatorUrl }); + const result = await facilitator.getBuyerData( + buyerAddress, + sellerAddress, + assetAddress, + escrowAddress, + 84532, + ); + + expect(result).toEqual(mockResponse); + expect(mockFetch).toHaveBeenCalledWith( + `${customFacilitatorUrl}/deferred/buyers/${buyerAddress}?seller=${sellerAddress}&asset=${assetAddress}&escrow=${escrowAddress}&chainId=84532`, + expect.objectContaining({ + method: "GET", + }), + ); + }); + }); + describe("flushEscrow", () => { const mockFlushAuthorization = { buyer: buyerAddress, diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index eac72b0479..27911602ca 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -300,12 +300,18 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { escrow: string, chainId: number, ): Promise { - const response = await fetch(`${facilitator.url}/deferred/buyers/${buyer}`, { + const params = new URLSearchParams(); + params.append("seller", seller); + params.append("asset", asset); + params.append("escrow", escrow); + params.append("chainId", chainId.toString()); + const queryString = params.toString(); + + const response = await fetch(`${facilitator.url}/deferred/buyers/${buyer}?${queryString}`, { method: "GET", headers: { "Content-Type": "application/json", }, - body: JSON.stringify({ seller, asset, escrow, chainId }), }); const responseJson = (await response.json()) as | DeferredBuyerDataResponse From 43d18f8011eff7e2ea952cd098d7c6b309e6ab46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 17 Oct 2025 13:41:29 -0300 Subject: [PATCH 114/116] fix(deferred): consider thawing funds when collecting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- examples/typescript/facilitator/index.ts | 64 +++++++++++++++++++ .../typescript/servers/express/.env-local | 2 +- solidity/deferred-escrow/addresses.json | 2 +- .../src/DeferredPaymentEscrow.sol | 5 +- .../src/IDeferredPaymentEscrow.sol | 2 + .../src/schemes/deferred/evm/facilitator.ts | 2 +- .../x402/src/schemes/deferred/evm/verify.ts | 13 ++-- .../src/types/shared/evm/deferredEscrowABI.ts | 1 + 8 files changed, 83 insertions(+), 8 deletions(-) diff --git a/examples/typescript/facilitator/index.ts b/examples/typescript/facilitator/index.ts index dee48b4c8a..20d15bdb0c 100644 --- a/examples/typescript/facilitator/index.ts +++ b/examples/typescript/facilitator/index.ts @@ -19,6 +19,7 @@ import { X402RequestSchema, DeferredEvmPayloadSchema, type X402Config, + DeferredEscrowFlushAuthorizationSignedSchema, } from "x402/types"; import { deferred } from "x402/schemes"; import { getNetworkName } from "x402/shared"; @@ -63,6 +64,19 @@ type SettleRequest = { paymentRequirements: PaymentRequirements; }; +type FlushRequest = { + flushAuthorization: { + buyer: string; + seller?: string; + asset?: string; + nonce: string; + expiry: number; + signature: string; + }; + escrow: string; + chainId: number; +}; + app.get("/verify", (req: Request, res: Response) => { res.json({ endpoint: "/verify", @@ -317,6 +331,55 @@ app.post("/deferred/vouchers/:id/:nonce/settle", async (req: Request, res: Respo } }); +// POST /deferred/buyers/:buyer/flush +app.post("/deferred/buyers/:buyer/flush", async (req: Request, res: Response) => { + try { + const body: FlushRequest = req.body; + + // Validate request body structure + if (!body.flushAuthorization || !body.escrow || !body.chainId) { + return res.status(400).json({ + success: false, + errorReason: "invalid_request_missing_fields", + transaction: "", + payer: "", + }); + } + + // Parse flush authorization + const flushAuthorization = DeferredEscrowFlushAuthorizationSignedSchema.parse( + body.flushAuthorization, + ); + + // Get the network from chainId + const network = getNetworkName(body.chainId); + + // Create a signer for the network + const signer = evm.createSigner(network, EVM_PRIVATE_KEY as `0x${string}`); + + // Call the flush function + const response = await deferred.evm.flushWithAuthorization( + signer, + flushAuthorization, + body.escrow as `0x${string}`, + ); + + if (!response.success) { + return res.status(400).json(response); + } + + res.json(response); + } catch (error) { + console.error("error", error); + res.status(400).json({ + success: false, + errorReason: "invalid_request", + transaction: "", + payer: "", + }); + } +}); + app.listen(PORT, () => { console.log(`Server listening at http://localhost:${PORT}`); @@ -324,4 +387,5 @@ app.listen(PORT, () => { console.log( `To settle a deferred voucher: POST http://localhost:${PORT}/deferred/vouchers/:id/:nonce/settle`, ); + console.log(`To flush escrow account: POST http://localhost:${PORT}/buyers/:buyer/flush`); }); diff --git a/examples/typescript/servers/express/.env-local b/examples/typescript/servers/express/.env-local index 6a9f41aa9f..5180243d22 100644 --- a/examples/typescript/servers/express/.env-local +++ b/examples/typescript/servers/express/.env-local @@ -1,7 +1,7 @@ FACILITATOR_URL=https://x402.org/facilitator NETWORK=base-sepolia ADDRESS= -DEFERRED_ESCROW=0x246fece47fa8c4a1a58348ad576685ef2bdb06c8 +DEFERRED_ESCROW=0x6f2abbc75b52bec6ca48959baaf8949b9a6acc9e # required if using the Base mainnet facilitator CDP_API_KEY_ID="Coinbase Developer Platform Key" diff --git a/solidity/deferred-escrow/addresses.json b/solidity/deferred-escrow/addresses.json index 248494edd7..ddf6c598c0 100644 --- a/solidity/deferred-escrow/addresses.json +++ b/solidity/deferred-escrow/addresses.json @@ -1,5 +1,5 @@ { "84532": { - "deferredPaymentEscrow": "0x246fece47fa8c4a1a58348ad576685ef2bdb06c8" + "deferredPaymentEscrow": "0x6f2abbc75b52bec6ca48959baaf8949b9a6acc9e" } } \ No newline at end of file diff --git a/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol b/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol index 3a9ca7d13b..ad25111095 100644 --- a/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol +++ b/solidity/deferred-escrow/src/DeferredPaymentEscrow.sol @@ -408,6 +408,7 @@ contract DeferredPaymentEscrow is ReentrancyGuard, EIP712, IDeferredPaymentEscro * @param depositAuthNonce The deposit authorization nonce (pass bytes32(0) if not using deposit auth) * @return voucherOutstanding Outstanding amount for the voucher * @return voucherCollectable Collectable amount for the voucher + * @return balance Balance of the escrow account * @return availableBalance Available balance (balance minus thawing amount) * @return allowance Allowance from asset contract * @return nonce Nonce from asset contract @@ -422,6 +423,7 @@ contract DeferredPaymentEscrow is ReentrancyGuard, EIP712, IDeferredPaymentEscro returns ( uint256 voucherOutstanding, uint256 voucherCollectable, + uint256 balance, uint256 availableBalance, uint256 allowance, uint256 nonce, @@ -434,8 +436,9 @@ contract DeferredPaymentEscrow is ReentrancyGuard, EIP712, IDeferredPaymentEscro uint256 alreadyCollected = $.voucherCollected[voucher.buyer][voucher.seller][voucher.asset][voucher.id]; (voucherOutstanding, voucherCollectable) = _getOutstandingAndCollectableAmount(voucher, alreadyCollected); - // Get available balance (balance minus thawing amount) + // Get balance and available balance (balance minus thawing amount) EscrowAccount memory account = $.accounts[voucher.buyer][voucher.seller][voucher.asset]; + balance = account.balance; availableBalance = account.balance - account.thawingAmount; // Get both allowance and nonce from asset contract diff --git a/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol b/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol index 2bb3923809..e911e37d05 100644 --- a/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol +++ b/solidity/deferred-escrow/src/IDeferredPaymentEscrow.sol @@ -410,6 +410,7 @@ interface IDeferredPaymentEscrow { * @param depositAuthNonce The deposit authorization nonce (pass bytes32(0) if not using deposit auth) * @return voucherOutstanding Outstanding amount for the voucher * @return voucherCollectable Collectable amount for the voucher + * @return balance Balance of the escrow account * @return availableBalance Available balance (balance minus thawing amount) * @return allowance Allowance from asset contract * @return nonce Nonce from asset contract @@ -424,6 +425,7 @@ interface IDeferredPaymentEscrow { returns ( uint256 voucherOutstanding, uint256 voucherCollectable, + uint256 balance, uint256 availableBalance, uint256 allowance, uint256 nonce, diff --git a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts index 3a28286781..37c83d3ff3 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/facilitator.ts @@ -300,7 +300,7 @@ export async function settleVoucher Date: Fri, 17 Oct 2025 14:19:53 -0300 Subject: [PATCH 115/116] chore(deferred): fix tests and improve error handling for useDeferredFacilitator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../schemes/deferred/evm/integration.test.ts | 4 ++++ .../x402/src/verify/useDeferred.test.ts | 7 +++--- .../packages/x402/src/verify/useDeferred.ts | 22 +++++++++++-------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts index 136f120859..b151a7a120 100644 --- a/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts +++ b/typescript/packages/x402/src/schemes/deferred/evm/integration.test.ts @@ -923,6 +923,7 @@ function mockBlockchainInteractionsSettle(wallet: SignerWallet return [ BigInt(1_000_000), // voucherOutstanding BigInt(1_000_000), // voucherCollectable + BigInt(10_000_000), // balance BigInt(10_000_000), // availableBalance BigInt(10_000_000), // allowance BigInt(0), // nonce @@ -959,6 +960,7 @@ function mockBlockchainInteractionsVerify(wallet: SignerWallet return [ BigInt(1_000_000), // voucherOutstanding BigInt(1_000_000), // voucherCollectable + BigInt(10_000_000), // balance BigInt(10_000_000), // availableBalance BigInt(10_000_000), // allowance BigInt(0), // nonce @@ -980,6 +982,7 @@ function mockBlockchainInteractionsSettleWithDepositAuth(wallet: SignerWallet { }); const facilitator = useDeferredFacilitator({ url: DEFAULT_FACILITATOR_URL }); - const result = await facilitator.flushEscrow(mockFlushAuthorization, escrowAddress, 84532); - expect(result).toEqual(mockResponse); - expect(result.success).toBe(false); - expect(result.errorReason).toBe("invalid_signature"); + await expect( + facilitator.flushEscrow(mockFlushAuthorization, escrowAddress, 84532), + ).rejects.toThrow("invalid_signature"); }); it("should use custom facilitator URL", async () => { diff --git a/typescript/packages/x402/src/verify/useDeferred.ts b/typescript/packages/x402/src/verify/useDeferred.ts index 27911602ca..f1aed4055f 100644 --- a/typescript/packages/x402/src/verify/useDeferred.ts +++ b/typescript/packages/x402/src/verify/useDeferred.ts @@ -207,14 +207,16 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { const response = await fetch(`${facilitator.url}/deferred/vouchers/${id}/${nonce}/verify`, { method: "POST", }); - const responseJson = await response.json(); + const responseJson = (await response.json()) as VerifyResponse; - if (response.status !== 200) { - const errorMessage = `Failed to verify voucher: ${response.statusText}`; + if (response.status !== 200 || "invalidReason" in responseJson) { + const errorMessage = + (responseJson as VerifyResponse).invalidReason || + `Failed to verify voucher: ${response.statusText}`; throw new Error(errorMessage); } - return responseJson as VerifyResponse; + return responseJson; } /** @@ -228,14 +230,14 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { const response = await fetch(`${facilitator.url}/deferred/vouchers/${id}/${nonce}/settle`, { method: "POST", }); - const responseJson = await response.json(); + const responseJson = (await response.json()) as SettleResponse; - if (response.status !== 200) { + if (response.status !== 200 || "errorReason" in responseJson) { const errorMessage = `Failed to settle voucher: ${response.statusText}`; throw new Error(errorMessage); } - return responseJson as SettleResponse; + return responseJson; } /** @@ -348,8 +350,10 @@ export function useDeferredFacilitator(facilitator: FacilitatorConfig) { ); const responseJson = (await response.json()) as DeferredFlushWithAuthorizationResponse; - if (response.status !== 200) { - const errorMessage = `Failed to flush escrow: ${response.statusText}`; + if (response.status !== 200 || "errorReason" in responseJson) { + const errorMessage = + (responseJson as DeferredFlushWithAuthorizationResponse).errorReason || + `Failed to flush escrow: ${response.statusText}`; throw new Error(errorMessage); } From 65f7755c44d93b9a7cf57b158b7e2772bbb600e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 22 Oct 2025 14:46:06 -0300 Subject: [PATCH 116/116] chore: remove spec documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- README.md | 44 +- specs/schemes/deferred/scheme_deferred.md | 15 - specs/schemes/deferred/scheme_deferred_evm.md | 314 ------------ .../scheme_deferred_evm_escrow_contract.md | 225 --------- .../scheme_deferred_evm_facilitator.md | 454 ------------------ .../scheme_deferred_evm_voucher_store.md | 168 ------- specs/x402-specification.md | 42 -- 7 files changed, 1 insertion(+), 1261 deletions(-) delete mode 100644 specs/schemes/deferred/scheme_deferred.md delete mode 100644 specs/schemes/deferred/scheme_deferred_evm.md delete mode 100644 specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md delete mode 100644 specs/schemes/deferred/scheme_deferred_evm_facilitator.md delete mode 100644 specs/schemes/deferred/scheme_deferred_evm_voucher_store.md diff --git a/README.md b/README.md index 953b29ae77..0fa8852e32 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ It specifies: 5. A REST specification for how a resource server can perform verification and settlement against a remote 3rd party server (`facilitator`) 6. A specification for a `X-PAYMENT-RESPONSE` header that can be used by resource servers to communicate blockchain transactions details to the client in their HTTP response -### V1 Protocol Sequencing (`exact` scheme) +### V1 Protocol Sequencing ![](./static/x402-protocol-flow.png) @@ -94,47 +94,6 @@ The following outlines the flow of a payment using the `x402` protocol. Note tha 12. `Resource server` returns a `200 OK` response to the `Client` with the resource they requested as the body of the HTTP response, and a `X-PAYMENT-RESPONSE` header containing the `Settlement Response` as Base64 encoded JSON if the payment was executed successfully. -### V1 Protocol Sequencing (`deferred` scheme) - -![](./static/x402-deferred-protocol-flow.png) - -The `deferred` scheme modifies the x402 protocol sequencing to allow for a deferred settlement to happen. The following steps outline the resource request and payment verification flow: - -1. `Client` makes an HTTP request to a `resource server`, optionally with a `X-PAYMENT-BUYER` header containing the `Client` address. - -2. `Resource server` processes the request and builds a `Payment Required Response` JSON object. The contents of the response include information in the `extra` field of the payment requirements, gathered from the facilitator: - - Voucher details: either a new voucher id for the `Client` to generate or the latest signed voucher for the `Client/Resource server` pair if it exists. - - Account balance: The `Client`'s onchain balance including outstanding vouchers to settle. Based on these values the `Client` can later opt to send a signed message to authorize deposits on their behalf. - - If no `X-PAYMENT-BUYER` is provided then the `Resource server` just responds with a new voucher id. - -3. `Resource server` responds with a `402 Payment Required` status and the `Payment Required Response` JSON object in the response body. - -4. `Client`sends an HTTP request with the `X-PAYMENT` header containing the `Payment Payload` to the resource server: - - If there is no previous `Client/Resource server` history, the `Client` will create and sign a new voucher as the payload. - - If there is a previous voucher, the `Client` aggregates payments on top of it before signing and adding it to the payload. - - Optionally, the `Client` can sign a deposit authorization to allow the `facilitator server` to escrow funds on their behalf. - -5. `Resource server` verifies the `Payment Payload` is valid by POSTing the `Payment Payload` and `Payment Requirements` to the `/verify` endpoint of a `facilitator server`. `Facilitator server` performs verification of the object based on the `scheme` and `network` of the `Payment Payload` and returns a `Verification Response`. - -6. If the `Verification Response` is valid: - - The `resource server` POSTs the validated voucher to the `facilitator server` for persistent storage using the endpoint `/deferred/vouchers` - - The `facilitator server` re-verifies the `Payment Payload` before storing the voucher, which makes the verification call on previous step not mandatory. - - If a deposit authorization is present the `facilitator server` will execute it. - -7. If the `Verification Response` is valid, the resource server performs the work to fulfill the request. If the `Verification Response` is invalid, the resource server returns a `402 Payment Required` status and a `Payment Required Response` JSON object in the response body. - -8. `Resource server` returns a `200 OK` response to the `Client` with the resource they requested as the body of the HTTP response, and a `X-PAYMENT-RESPONSE` header. - -At this point the `Client` has "paid for" the resource access by means of a signed voucher. The `facilitator server` stores the vouchers which can be redeemed at any time. The settlement sequencing then is as follows: - -1. `Resource server` requests a settlement to happen by POSTing to a special `facilitator server` endpoint: `POST /deferred/vouchers/settle` - -2. `Facilitator server` retrieves the voucher to be settled and submits the transaction to the blockchain based on the `scheme` and `network` of the `Payment Payload`. - -3. `Facilitator server` waits for the voucher settlement to be confirmed on the blockchain. - -4. `Facilitator server` returns a `Payment Execution Response` to the resource server. - ### Type Specifications #### Data types @@ -190,7 +149,6 @@ At this point the `Client` has "paid for" the resource access by means of a sign // Extra information about the payment details specific to the scheme // For `exact` scheme on a EVM network, expects extra to contain the records `name` and `version` pertaining to asset - // For `deferred` scheme on a EVM network, expects extra to contain the records `type`, `voucher` and `signature` extra: object | null; } ``` diff --git a/specs/schemes/deferred/scheme_deferred.md b/specs/schemes/deferred/scheme_deferred.md deleted file mode 100644 index 77784d0555..0000000000 --- a/specs/schemes/deferred/scheme_deferred.md +++ /dev/null @@ -1,15 +0,0 @@ -# Scheme: `deferred` - -## Summary - -`deferred` is a scheme designed to support trust minimized micro-payments. Unlike the `exact` scheme, which requires a payment to be executed immediately and fully on-chain, `deferred` allows clients to issue signed vouchers (IOUs) off-chain, which can later be aggregated and redeemed by the seller. This scheme enables payments smaller than the minimum feasible on-chain transaction cost. - -`deferred` payment scheme requires the seller to store and manage the buyer's vouchers until their eventual on chain settlement. To simplify their setup sellers might choose to offload this task to trusted third parties providing these services, i.e facilitators. - -## Example Use Cases - -- AI agents or automated clients. -- Consuming an API requiring micro cent cost per request. -- Any case where payments are smaller than on-chain settlement costs. - -## Appendix \ No newline at end of file diff --git a/specs/schemes/deferred/scheme_deferred_evm.md b/specs/schemes/deferred/scheme_deferred_evm.md deleted file mode 100644 index d6dd0582af..0000000000 --- a/specs/schemes/deferred/scheme_deferred_evm.md +++ /dev/null @@ -1,314 +0,0 @@ -# Scheme: `deferred` on `EVM` - -## Summary - -The `deferred` scheme on EVM chains uses `EIP-712` signed vouchers to represent payment commitments from a buyer to a seller. Before issuing vouchers, the buyer deposits funds—denominated in a specific `ERC-20` token—into an on-chain escrow earmarked for the seller. Each voucher authorizes a payment against that escrow balance, and explicitly specifies the asset being used. -Sellers can collect and aggregate these signed messages over time, choosing when to redeem them on-chain and settling the total amount in a single transaction. -This design enables efficient, asset-flexible micropayments without incurring prohibitive gas costs for every interaction. - -## `X-Payment` header payload - -The `payload` field of the `X-PAYMENT` header must contain the following fields: - -- `signature`: The signature of the `EIP-712` voucher. -- `voucher`: parameters required to reconstruct the signed message for the operation. -- `depositAuthorization` (optional): A signed authorization allowing the facilitator to deposit funds into escrow on behalf of the buyer. This enables gasless deposits for new buyers or when additional funds are needed. - -### Voucher Fields - -- `id`: Unique identifier for the voucher (bytes32) -- `buyer`: Address of the payment initiator (address) -- `seller`: Address of the payment recipient (address) -- `valueAggregate`: Total outstanding amount in the voucher, monotonically increasing (uint256) -- `asset`: ERC-20 token address (address) -- `timestamp`: Last aggregation timestamp (uint64) -- `nonce`: Incremented with each aggregation (uint256) -- `escrow`: Address of the escrow contract (address) -- `chainId`: Network chain ID (uint256) -- `expiry`: Expiration timestamp after which voucher cannot be collected (uint64) - -Example: - -```json -{ - "signature": "0x3a2f7e3b6c1d8e9c0f64f8724e5cfb8bfe9a3cdb1ad6e4a876f7d418e47e96b11a23346a1b0e60c8d3a4c4fd0150a244ab4b0e6d6c5fa4103f8fa8fd2870a3c81b", - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "2000000000000000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1740673000, - "nonce": 3, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1740759400 - } -} -``` - -Full `X-PAYMENT` header (without deposit authorization): - -```json -{ - "x402Version": 1, - "scheme": "deferred", - "network": "base-sepolia", - "payload": { - "signature": "0x3a2f7e3b6c1d8e9c0f64f8724e5cfb8bfe9a3cdb1ad6e4a876f7d418e47e96b11a23346a1b0e60c8d3a4c4fd0150a244ab4b0e6d6c5fa4103f8fa8fd2870a3c81b", - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "2000000000000000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1740673000, - "nonce": 3, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1740759400 - } - } -} -``` - -### Deposit Authorization Fields (optional) - -The `depositAuthorization` object enables gasless escrow deposits by allowing the facilitator to execute deposits on behalf of the buyer. This is particularly useful for first-time buyers or when escrow balance needs to be topped up. The structure consists of two parts: - -**Required:** -- `depositAuthorization`: EIP-712 signed authorization for the escrow contract - - `buyer`: Address of the buyer authorizing the deposit (address) - - `seller`: Address of the seller receiving the escrow deposit (address) - - `asset`: ERC-20 token contract address (address) - - `amount`: Amount to deposit in atomic token units (uint256) - - `nonce`: Unique bytes32 for replay protection (bytes32) - - `expiry`: Authorization expiration timestamp (uint64) - - `signature`: EIP-712 signature of the deposit authorization (bytes) - -**Optional:** -- `permit`: EIP-2612 permit for the ERC-20 token (if token supports permits) - - `owner`: Token owner address (address) - - `spender`: Escrow contract address (address) - - `value`: Token amount to approve (uint256) - - `nonce`: Token contract nonce for the permit (uint256/bigint) - - `deadline`: Permit expiration timestamp (uint256) - - `domain`: Token's EIP-712 domain - - `name`: Token name (string) - - `version`: Token version (string) - - `signature`: EIP-2612 signature of the permit (bytes) - -Example `X-PAYMENT` header with deposit authorization: - -```json -{ - "x402Version": 1, - "scheme": "deferred", - "network": "base-sepolia", - "payload": { - "signature": "0x3a2f7e3b6c1d8e9c0f64f8724e5cfb8bfe9a3cdb1ad6e4a876f7d418e47e96b11a23346a1b0e60c8d3a4c4fd0150a244ab4b0e6d6c5fa4103f8fa8fd2870a3c81b", - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "2000000000000000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1740673000, - "nonce": 3, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1740759400 - }, - "depositAuthorization": { - "permit": { - "owner": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "spender": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "value": "5000000", - "nonce": "0", - "deadline": 1740759400, - "domain": { - "name": "USD Coin", - "version": "2" - }, - "signature": "0x8f9e2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f1b" - }, - "depositAuthorization": { - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "amount": "5000000", - "nonce": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", - "expiry": 1740759400, - "signature": "0xbfdc3d0ae7663255972fdf5ce6dfc7556a5ac1da6768e4f4a942a2fa885737db5ddcb7385de4f4b6d483b97beb6a6103b46971f63905a063deb7b0cfc33473411b" - } - } - } -} -``` - -## `paymentRequirements` extra object - -The `extra` object in the "Payment Required Response" should contain the following fields: - -### Common Fields -- `type`: Indicates whether this is a `"new"` voucher or an `"aggregation"` of an existing voucher -- `account` (optional): Current escrow account details for the buyer-seller-asset tuple - - `balance`: Current escrow balance in atomic token units - - `assetAllowance`: Current token allowance for the escrow contract - - `assetPermitNonce`: Current permit nonce for the token contract - - `facilitator`: Address of the facilitator managing the escrow - -### For New Vouchers (`type: "new"`) -- `voucher`: A simplified voucher object containing: - - `id`: The voucher id to use for the new voucher (bytes32) - - `escrow`: The address of the escrow contract (address) - -### For Aggregation (`type: "aggregation"`) -- `signature`: The signature of the latest voucher corresponding to the given `id` (bytes) -- `voucher`: The complete latest voucher corresponding to the given `id` (all voucher fields) - -### Examples - -**New voucher (without account details):** - -```json -{ - "extra": { - "type": "new", - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27" - } - } -} -``` - -**Aggregation (with account details):** - -```json -{ - "extra": { - "type": "aggregation", - "account": { - "balance": "5000000", - "assetAllowance": "5000000", - "assetPermitNonce": "0", - "facilitator": "https://facilitator.com" - }, - "signature": "0x3a2f7e3b6c1d8e9c0f64f8724e5cfb8bfe9a3cdb1ad6e4a876f7d418e47e96b11a23346a1b0e60c8d3a4c4fd0150a244ab4b0e6d6c5fa4103f8fa8fd2870a3c81b", - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "2000000000000000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1740673000, - "nonce": 3, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1740759400 - } - } -} -``` - -## Verification - -The following steps are required to verify a deferred payment: - -1. **Signature validation**: Verify the EIP-712 signature is valid -2. **Payment requirements matching**: - - Verify scheme is `"deferred"` - - Verify `paymentPayload.network` matches `paymentRequirements.network` - - Verify `paymentRequirements.payTo` matches `paymentPayload.voucher.seller` - - Verify `paymentPayload.voucher.asset` matches `paymentRequirements.asset` - - Verify `paymentPayload.voucher.chainId` matches the chain specified by `paymentRequirements.network` -3. **Voucher aggregation validation** (if aggregating an existing voucher): - - Verify `nonce` equals the previous `nonce + 1` - - Verify `valueAggregate` is equal to the previous `valueAggregate + paymentRequirements.maxAmountRequired` - - Verify `timestamp` is greater than the previous `timestamp` - - Verify `buyer`, `seller`, `asset`, `escrow` and `chainId` all match the previous voucher values -4. **Amount validation**: - - Verify `paymentPayload.voucher.valueAggregate` is enough to cover `paymentRequirements.maxAmountRequired` plus previous voucher value aggregate if it's an aggregate voucher -5. **Escrow balance check**: - - Verify the `buyer` has enough of the `asset` (ERC20 token) in the escrow to cover the valueAggregate in the `payload.voucher` - - Verify `id` has not been already collected in the escrow, or if it has, that the new balance is greater than what was already paid (in which case the difference will be paid) -6. **Expiry validation**: - - Verify the voucher has not expired by checking that the current timestamp is less than or equal to `expiry` - - Verify `paymentPayload.voucher.expiry` and `paymentPayload.voucher.timestamp` dates make sense -7. **Deposit authorization validation** (if present): - - Verify the `depositAuthorization.depositAuthorization.signature` is a valid EIP-712 signature - - Verify `depositAuthorization.depositAuthorization.buyer` matches `paymentPayload.voucher.buyer` - - Verify `depositAuthorization.depositAuthorization.seller` matches `paymentPayload.voucher.seller` - - Verify `depositAuthorization.depositAuthorization.asset` matches `paymentPayload.voucher.asset` - - Verify `depositAuthorization.depositAuthorization.expiry` has not passed - - Verify the nonce has not been used before by checking the escrow contract - - If `permit` is present: - - Verify the `permit.signature` is a valid EIP-2612 signature - - Verify the permit nonce is valid by checking the token contract - - Verify `permit.owner` matches the buyer - - Verify `permit.spender` matches the escrow contract address - - Verify `permit.value` is sufficient to cover the deposit amount - - Verify `permit.deadline` has not passed -8. **Transaction simulation** (optional but recommended): - - Simulate the voucher collection to ensure the transaction would succeed on-chain - -## Deposit Authorization Execution - -When a `depositAuthorization` is included in the payment payload, the facilitator should execute it before storing the voucher. This ensures that the buyer has sufficient funds escrowed before the voucher is stored, preventing invalid vouchers from being accepted. - -## Settlement - -Settlement is performed via the facilitator calling the `collect` function on the escrow contract with the `payload.signature` and `payload.voucher` parameters from the `X-PAYMENT` header. This can be initiated by buyer's request or the facilitator holding the vouchers could trigger automatic settlement based on pre-agreed conditions. - -Multiple vouchers may be collected in a single transaction, using the `collectMany` function. - -## Appendix - -### `X-Payment-Buyer` header - -The `X-PAYMENT-BUYER` header allows buyers to notify sellers about their identity before signing any voucher or message. This enables sellers to determine whether to request a new voucher or check their voucher store for existing vouchers for further aggregation. It's important to note this header requires no proof of identity, the seller assumes the buyer is who it claims to be. This is not a problem however since the payment flow will later require valid signatures which an impostor wont be able to forge. - -The header contains the buyer's EVM address as a simple string: - -``` -X-PAYMENT-BUYER: 0x209693Bc6afc0C5328bA36FaF03C514EF312287C -``` - -The buyer needs to add this header when initially requesting access to a resource. Failing to provide the header will result in new vouchers being created on each interaction, defeating the purpose of the `deferred` scheme. - -Example 402 response with an existing voucher: -```json -{ - "x402Version": 1, - "accepts": [{ - "scheme": "deferred", - "network": "base-sepolia", - "maxAmountRequired": "1000000", - "payTo": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "extra": { - "type": "aggregation", - "signature": "0x3a2f7e3b...", - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "5000000", - "nonce": 2, - // ... other voucher fields - } - } - }] -} -``` - -### Facilitator specification - -Facilitators supporting the `deferred` scheme should implement a voucher store for sellers and new APIs. Specification for these can be found here: -- [Voucher Store specification](./voucher_store.md) -- [Deferred Facilitator specification](./scheme_deferred_evm_facilitator.md) - -### Escrow contract specification - -The full specification for the deferred escrow contract can be found here: [DeferredPaymentEscrow specification](./scheme_deferred_evm_escrow_contract.md) \ No newline at end of file diff --git a/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md b/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md deleted file mode 100644 index 1ade49cf83..0000000000 --- a/specs/schemes/deferred/scheme_deferred_evm_escrow_contract.md +++ /dev/null @@ -1,225 +0,0 @@ - -# DeferredPaymentEscrow Contract Specification - -## Summary - -The `DeferredPaymentEscrow` contract enables micropayments using an escrow-based voucher system. Buyers deposit ERC-20 tokens into escrow accounts for specific sellers, then issue off-chain EIP-712 signed vouchers that sellers can redeem against those deposits. This approach allows for efficient aggregation of many small payments before on-chain settlement, while maintaining security through cryptographic signatures and time-bounded withdrawals. - -The contract is designed for scenarios where payments are frequent but small (micropayments), making individual on-chain transactions economically inefficient. It provides strong guarantees to both parties: buyers retain control over their deposited funds through a thawing mechanism, while sellers can collect payments immediately when vouchers are presented. - -## Contract Overview - -The contract manages deposits, withdrawals, and voucher redemption: - -- **Deposits**: Buyers deposit ERC-20 tokens for specific sellers -- **Vouchers**: Off-chain signed promises to pay that aggregate over time -- **Collection**: Sellers redeem vouchers against escrow balances -- **Withdrawal**: Buyers can withdraw unused funds after a thawing period -- **Authorization**: EIP-712 signed operations for gasless interactions (designed for x402 Facilitators to be able to abstract escrow management actions from buyers) - -## Data Structures - -### EscrowAccount -```solidity -struct EscrowAccount { - uint256 balance; // Total deposited balance (includes thawing amount) - uint256 thawingAmount; // Amount currently thawing for withdrawal (subset of balance) - uint64 thawEndTime; // When thawing completes -} -``` - -**Important**: The `balance` field represents the total amount of tokens held in the escrow account, which includes any amount currently thawing. The `thawingAmount` is a subset of the `balance` that has been marked for withdrawal after the thawing period. Available funds for new thawing operations = `balance - thawingAmount`. - -### Voucher -```solidity -struct Voucher { - bytes32 id; // Unique identifier per buyer-seller pair - address buyer; // Payment initiator - address seller; // Payment recipient - uint256 valueAggregate; // Total accumulated amount (monotonically increasing) - address asset; // ERC-20 token address - uint64 timestamp; // Last aggregation timestamp - uint256 nonce; // Incremented with each aggregation - address escrow; // This contract's address - uint256 chainId; // Network chain ID - uint64 expiry; // Expiration timestamp -} -``` - -## Account Structure - -The contract uses a triple-nested mapping to organize escrow accounts: -``` -buyer → seller → asset → EscrowAccount -``` - -This structure ensures: -- Each buyer-seller pair has independent accounts -- Different assets (tokens) are tracked separately -- Clean separation of concerns between relationships - -## Payment Flow - -### 1. Deposit Phase -``` -Buyer → deposit(seller, asset, amount) → Escrow Contract - -OR - -Buyer → depositWithAuthorization(auth, signature) → Escrow Contract -``` - -### 2. Service & Voucher Phase -``` -Buyer ↔ Seller (off-chain interactions) -Buyer → signs Voucher(id, valueAggregate, ...) → Seller -``` - -### 3. Collection Phase -``` -Seller → collect(voucher, signature) → Escrow Contract -Escrow Contract → transfer(asset, amount) → Seller -``` - -### 4. Withdrawal Phase (if needed) -``` -Buyer → thaw(seller, asset, amount) → Escrow Contract -[wait THAWING_PERIOD] -Buyer → withdraw(seller, asset) → Escrow Contract -``` - -## Verification - -To verify a payment in the `deferred` scheme: - -1. **Signature Validation**: Verify the voucher signature using EIP-712 and ERC-1271 -2. **Contract Verification**: Ensure `voucher.escrow` matches the expected contract address -3. **Chain Verification**: Ensure `voucher.chainId` matches the current network -4. **Expiry Check**: Verify `block.timestamp <= voucher.expiry` -5. **Balance Check**: Verify escrow account has sufficient balance for collection -6. **Aggregation Validation**: Ensure `voucher.valueAggregate >= previous_collections` - -## Settlement - -Settlement occurs when sellers call the `collect` function: - -1. **Validation**: Contract validates voucher parameters and signature -2. **Amount Calculation**: Determines collectable amount based on: - - Total voucher value (`valueAggregate`) - - Previously collected amounts for this voucher ID - - Available balance in escrow account -3. **State Updates**: Records new collected amount and updates escrow balance -4. **Transfer**: Sends tokens directly to seller -5. **Events**: Emits collection events for off-chain tracking - -### Partial Collection - -If escrow balance is insufficient for the full voucher amount: -- Contract collects only the available amount -- Voucher remains valid for future collection of remaining amount -- Prevents voucher failures due to temporary fund shortages - -**Note for Sellers**: Before accepting a voucher off-chain, sellers should verify that the escrow account has sufficient balance to cover the voucher amount. This can be checked using `getOutstandingAndCollectableAmount(voucher)` which returns both the outstanding amount owed and the amount that can actually be collected immediately. - -## Withdrawal Protection - -The thawing mechanism protects sellers from sudden fund withdrawals: - -1. **Thaw Initiation**: Buyer calls `thaw(seller, asset, amount)` (calling `thaw()` multiple times will add to the thawing amount and reset the timer) -2. **Thawing Period**: Set at contract deployment (standard value is 1 day, though other escrow instances can be deployed with different thawing periods if needed) -3. **Seller Collection**: Sellers can still collect from full balance during thawing -4. **Withdrawal**: After thawing period, buyer can withdraw thawed amount -5. **Cancellation**: Buyers can cancel thawing at any time before completion - -## Authorization System - -### Gasless Operations - -The contract supports EIP-712 signed authorizations for gasless operations, designed for x402: - -### Deposit Authorization -Allows x402 Facilitators to execute deposits on behalf of buyers: -```solidity -struct DepositAuthorization { - address buyer; // Who is authorizing - address seller; // Recipient - address asset; // Token to deposit - uint256 amount; // Amount to deposit - bytes32 nonce; // Random bytes32 for replay protection - uint64 expiry; // Authorization expiration -} -``` - -### Flush Authorization -Enables x402 Facilitators to "flush" funds for buyers (withdraws any funds that have completed thawing, then starts thawing any remaining balance): -```solidity -struct FlushAuthorization { - address buyer; // Who is authorizing - address seller; // Specific account to flush - address asset; // Specific asset to flush - bytes32 nonce; // Random bytes32 for replay protection - uint64 expiry; // Authorization expiration -} -``` - -### Flush All Authorization -Allows batch withdrawal from all of a buyer's escrow accounts (performs flush operation on every account): -```solidity -struct FlushAllAuthorization { - address buyer; // Who is authorizing - bytes32 nonce; // Random bytes32 for replay protection - uint64 expiry; // Authorization expiration -} -``` - -## Contract Interface - -### Core Functions - -### Deposits -- `deposit(address seller, address asset, uint256 amount)` - Direct deposit -- `depositTo(address buyer, address seller, address asset, uint256 amount)` - Third-party deposit -- `depositMany(address asset, DepositInput[] deposits)` - Batch deposits -- `depositWithAuthorization(DepositAuthorization auth, bytes signature)` - Gasless deposit - -### Withdrawals -- `thaw(address seller, address asset, uint256 amount)` - Initiate withdrawal -- `cancelThaw(address seller, address asset)` - Cancel ongoing thaw -- `withdraw(address seller, address asset)` - Complete withdrawal -- `flushWithAuthorization(FlushAuthorization auth, bytes signature)` - Gasless specific flush -- `flushAllWithAuthorization(FlushAllAuthorization auth, bytes signature)` - Gasless batch flush - -### Collections -- `collect(Voucher voucher, bytes signature)` - Single voucher redemption -- `collectMany(SignedVoucher[] vouchers)` - Batch voucher redemption - -### View Functions -- `getAccount(address buyer, address seller, address asset)` → `EscrowAccount` - Get escrow account details -- `getAccountDetails(address buyer, address seller, address asset, bytes32[] voucherIds, uint256[] valueAggregates)` → `(uint256 balance, uint256 allowance, uint256 nonce)` - Get account details including available balance after accounting for pending vouchers, token allowance, and permit nonce. Returns: - - `balance`: Available escrow balance minus thawing amount and minus amounts needed for the provided voucher collections - - `allowance`: Current token allowance granted to the escrow contract - - `nonce`: Current EIP-2612 permit nonce for the buyer on the asset token contract -- `getVoucherCollected(address buyer, address seller, address asset, bytes32 voucherId)` → `uint256` - Get total amount already collected for this voucher ID -- `getOutstandingAndCollectableAmount(Voucher voucher)` → `(uint256 outstanding, uint256 collectable)` - Returns outstanding amount still owed and amount that can be collected immediately given current escrow balance -- `isVoucherSignatureValid(Voucher voucher, bytes signature)` → `bool` - Validate voucher signature -- `isDepositAuthorizationValid(DepositAuthorization auth, bytes signature)` → `bool` - Validate deposit authorization signature -- `isFlushAuthorizationValid(FlushAuthorization auth, bytes signature)` → `bool` - Validate flush authorization signature -- `isFlushAllAuthorizationValid(FlushAllAuthorization auth, bytes signature)` → `bool` - Validate flush all authorization signature - -### Constants -- `THAWING_PERIOD()` → `uint256` - Withdrawal thawing period (immutable, set at deployment) -- `MAX_THAWING_PERIOD()` → `uint256` - Maximum allowed thawing period (30 days) -- `DOMAIN_SEPARATOR()` → `bytes32` - EIP-712 domain separator - -## Appendix - -### Multi-Chain Deployment - -While each contract instance operates on a single chain, the design supports multi-chain deployments: -- Vouchers include `chainId` for chain-specific validation -- Contract will be deployed using Safe Singleton Factory for deterministic addresses across chains -- Cross-chain coordination must be handled at the application layer - -### Reference Implementation - -A reference implementation for this contract is provided with this repository, it can be found at [DeferredPaymentEscrow](../../../solidity/deferred-escrow/README.md) \ No newline at end of file diff --git a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md b/specs/schemes/deferred/scheme_deferred_evm_facilitator.md deleted file mode 100644 index 808fc8145a..0000000000 --- a/specs/schemes/deferred/scheme_deferred_evm_facilitator.md +++ /dev/null @@ -1,454 +0,0 @@ -# Deferred Facilitator Specification - -## Summary - -This specification defines the REST API endpoints that facilitators must implement to support the `deferred` payment scheme. These endpoints enable sellers to store, retrieve, and settle vouchers through the facilitator's voucher store infrastructure. Vouchers are identified by a unique combination of `id` (64-character hex string) and `nonce` (non-negative integer). - -All endpoints are served under the facilitator's deferred scheme namespace: `${FACILITATOR_URL}/deferred/` - -## Authentication - -Read only endpoints do not require any form of authentication. Any information that can be retrieved by these endpoints will eventually be publicly available on chain. -As for write endpoints, they do not require traditional authentication but instead they rely on verification of signed messages. See each endpoint for details. - -## Required APIs - -### GET /buyers/:buyer - -Retrieves buyer data for a specific buyer, including escrow account balance, asset allowance, permit nonce, and the latest available voucher for a particular seller and asset. - -**Query Parameters:** -- `seller` (required): Seller address (e.g., "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D") -- `asset` (required): Asset address (e.g., "0x081827b8c3aa05287b5aa2bc3051fbe638f33152") -- `escrow` (required): Escrow address (e.g., "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27") -- `chainId` (required): Chain ID (e.g., 84532) - -**Example Request:** -``` -GET /buyers/0x209693Bc6afc0C5328bA36FaF03C514EF312287C?seller=0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D&asset=0x081827b8c3aa05287b5aa2bc3051fbe638f33152&escrow=0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27&chainId=84532 -``` - -**Response (200 OK):** -```json -{ - "balance": "10000000", - "assetAllowance": "5000000", - "assetPermitNonce": "0", - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "5000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1740673000, - "nonce": 2, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1740759400, - "signature": "0x3a2f7e3b..." - } -} -``` - -**Response (200 OK - No voucher available):** -```json -{ - "balance": "10000000", - "assetAllowance": "5000000", - "assetPermitNonce": "0" -} -``` - -**Response (400 Bad Request):** -```json -{ - "error": "Invalid parameters" -} -``` - -### POST /vouchers - -Stores a new signed voucher in the facilitator's voucher store after verifying it. The verification should be exactly the same as you'd get by POSTing to /verify. This allows for replacing that call for one to this endpoint. - -If the payment payload contains a `depositAuthorization`, the facilitator must execute it **before** storing the voucher: -1. If a `permit` is present, call the token contract's `permit` function -2. Call the escrow contract's `depositWithAuthorization` function -3. Verify the deposit succeeded by checking the escrow balance -4. Only then store the voucher - -**Request Body (without depositAuthorization):** -```json -{ - "paymentPayload": { - "x402Version": 1, - "network": "base-sepolia", - "scheme": "deferred", - "payload": { - "signature": "0x4b3f8e...", - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "6000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1740673100, - "nonce": 3, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1740759400 - } - } - }, - "paymentRequirements": { - "x402Version": 1, - "network": "base-sepolia", - "scheme": "deferred", - "recipient": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "amount": "1000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "extra": { - "type": "aggregation", - "signature": "0x3a2f7e3b...", - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "5000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1740673000, - "nonce": 2, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1740759400 - } - } - } -} -``` - -**Request Body (with depositAuthorization):** -```json -{ - "paymentPayload": { - "x402Version": 1, - "network": "base-sepolia", - "scheme": "deferred", - "payload": { - "signature": "0x4b3f8e...", - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "1000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1740673000, - "nonce": 1, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1740759400 - }, - "depositAuthorization": { - "permit": { - "owner": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "spender": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "value": "5000000", - "nonce": "0", - "deadline": 1740759400, - "domain": { - "name": "USD Coin", - "version": "2" - }, - "signature": "0x8f9e2a3b..." - }, - "depositAuthorization": { - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "amount": "5000000", - "nonce": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", - "expiry": 1740759400, - "signature": "0xbfdc3d0a..." - } - } - } - }, - "paymentRequirements": { - "x402Version": 1, - "network": "base-sepolia", - "scheme": "deferred", - "recipient": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "amount": "1000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "extra": { - "type": "new", - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27" - } - } - } -} -``` - -**Response (201 Created):** -```json -{ - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "6000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1740673100, - "nonce": 3, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1740759400, - "signature": "0x4b3f8e..." -} -``` - -**Response (400 Bad Request):** -```json -{ - "isValid": false, - "invalidReason": "invalid_deferred_evm_payload_signature", - "payer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C" -} -``` - -### POST /vouchers/:id/:nonce/settle - -Initiates on-chain settlement of a voucher by calling the escrow contract's `collect` function. - -**Request Body (optional):** -```json -{ - "gasPrice": "20000000000", - "gasLimit": "150000" -} -``` - -**Response (200 OK):** -```json -{ - "success": true, - "transactionHash": "0xabc123...", - "collectedAmount": "6000000", - "network": "base-sepolia" -} -``` - -**Response (400 Bad Request):** -```json -{ - "success": false, - "error": "Voucher not found" -} -``` - -## Optional APIs - -These endpoints are not required for the x402 deferred handshake between a buyer and a seller but might come in handy for audit, visualization or observability purposes. - -### GET /vouchers/:id/:nonce - -Retrieves a specific voucher by ID and nonce. - -**Response (200 OK):** -```json -{ - "voucher": { /* voucher fields */ }, - "signature": "0x3a2f7e3b..." -} -``` - -### GET /vouchers/:id - -Retrieves all vouchers in a series, sorted by nonce (descending). - -**Query Parameters:** -- `limit` (optional): Maximum results (default: 100) -- `offset` (optional): Pagination offset (default: 0) - -**Response (200 OK):** -```json -{ - "vouchers": [ - { - "voucher": { /* voucher fields */ }, - "signature": "0x4b3f8e..." - } - ], - "pagination": { - "limit": 100, - "offset": 0, - "total": 5 - } -} -``` - -### GET /vouchers - -Queries vouchers with filtering. - -**Query Parameters:** -- `buyer` (optional): Filter by buyer address -- `seller` (optional): Filter by seller address -- `latest` (optional): If true, return only highest nonce per series -- `limit` (optional): Maximum results (default: 100) -- `offset` (optional): Pagination offset (default: 0) - -**Response (200 OK):** -```json -{ - "vouchers": [ - { - "voucher": { /* voucher fields */ }, - "signature": "0x3a2f7e3b..." - } - ], - "pagination": { - "limit": 100, - "offset": 0, - "total": 42 - } -} -``` - -### POST /vouchers/:id/:nonce/verify - -Verifies a voucher's validity without settling it. - -**Response (200 OK):** -```json -{ - "valid": true, - "escrowBalance": "10000000", - "collectableAmount": "6000000", - "alreadyCollected": "0" -} -``` - -**Response (200 OK - Invalid):** -```json -{ - "valid": false, - "reason": "Voucher expired" -} -``` - -### GET /vouchers/:id/:nonce/collections - -Retrieves settlement history for a voucher. - -**Query Parameters:** -- `limit` (optional): Maximum results (default: 100) -- `offset` (optional): Pagination offset (default: 0) - -**Response (200 OK):** -```json -{ - "collections": [ - { - "voucherId": "0x9f8d3e4a...", - "voucherNonce": 3, - "transactionHash": "0xabc123...", - "collectedAmount": "6000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "chainId": 84532, - "collectedAt": 1740673200 - } - ], - "pagination": { - "limit": 100, - "offset": 0, - "total": 1 - } -} -``` - - -### GET /vouchers/available/:buyer/:seller - -Returns the most suitable voucher for aggregation between a buyer-seller pair. - -**Response (200 OK):** -```json -{ - "voucher": { - "id": "0x9f8d3e4a2c7b9d04dcd11c9f4c2b22b0a6f87671e7b8c3a2ea95b5dbdf4040bc", - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "valueAggregate": "5000000", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "timestamp": 1740673000, - "nonce": 2, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532, - "expiry": 1740759400 - }, - "signature": "0x3a2f7e3b..." -} -``` - -**Response (404 Not Found):** No vouchers exist for this pair - -### POST /buyers/:buyer/flush - -Flushes an escrow account using a signed flush authorization. This operation allows a buyer to authorize the facilitator to help them recover escrowed funds by: -1. Withdrawing any funds that have completed their thawing period -2. Initiating thawing for any remaining balance - -The flush authorization can be either: -- **Specific flush**: When `seller` and `asset` are provided, flushes only that specific account -- **Flush all**: When `seller` or `asset` are undefined, flushes all escrow accounts for the buyer - -**Request Body:** -```json -{ - "flushAuthorization": { - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "seller": "0xA1c7Bf3d421e8A54D39FbBE13f9f826E5B2C8e3D", - "asset": "0x081827b8c3aa05287b5aa2bc3051fbe638f33152", - "nonce": "0x0000000000000000000000000000000000000000000000000000000000000000", - "expiry": 1740759400, - "signature": "0xbfdc3d0a..." - }, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532 -} -``` - -**Request Body (Flush All - seller/asset undefined):** -```json -{ - "flushAuthorization": { - "buyer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - "nonce": "0x0000000000000000000000000000000000000000000000000000000000000000", - "expiry": 1740759400, - "signature": "0xbfdc3d0a..." - }, - "escrow": "0x7cB1A5A2a2C9e91B76914C0A7b7Fb3AefF3BCA27", - "chainId": 84532 -} -``` - -**Response (200 OK):** -```json -{ - "success": true, - "transaction": "0xabc123...", - "payer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C" -} -``` - -**Response (400 Bad Request):** -```json -{ - "success": false, - "errorReason": "invalid_deferred_evm_payload_flush_authorization_signature", - "transaction": "", - "payer": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C" -} -``` - diff --git a/specs/schemes/deferred/scheme_deferred_evm_voucher_store.md b/specs/schemes/deferred/scheme_deferred_evm_voucher_store.md deleted file mode 100644 index ff23fb9575..0000000000 --- a/specs/schemes/deferred/scheme_deferred_evm_voucher_store.md +++ /dev/null @@ -1,168 +0,0 @@ -# Voucher Store Specification - -## Summary - -The Voucher Store is a critical component of the X402 `deferred` payment scheme that manages the persistence and retrieval of signed payment vouchers and their settlement records. It serves as the data layer for sellers and facilitators to track off-chain payment obligations and their eventual on-chain settlements. - -This specification defines the interface and requirements for implementing a voucher store in the deferred EVM payment system, ensuring consistent behavior across different implementations (in-memory, database-backed, etc.). - -## Overview - -The voucher store manages three key concepts: - -1. **Vouchers**: EIP-712 signed payment commitments from buyers to sellers -2. **Voucher Series**: A sequence of vouchers sharing the same ID but with different nonces (representing aggregations) -3. **Collections**: Records of on-chain settlements for vouchers - -## Data Model - -### Voucher Structure - -A voucher contains the following fields: - -| Field | Type | Description | -|-------|------|-------------| -| `id` | bytes32 | Unique identifier for the voucher series | -| `buyer` | address | Address of the payment initiator | -| `seller` | address | Address of the payment recipient | -| `valueAggregate` | uint256 | Total accumulated amount (monotonically increasing) | -| `asset` | address | ERC-20 token contract address | -| `timestamp` | uint64 | Last aggregation timestamp | -| `nonce` | uint256 | Incremented with each aggregation | -| `escrow` | address | Address of the escrow contract | -| `chainId` | uint256 | Network chain ID | -| `expiry` | uint64 | Expiration timestamp | -| `signature` | bytes | EIP-712 signature of the voucher | - -### Collection Structure - -A collection record contains: - -| Field | Type | Description | -|-------|------|-------------| -| `voucherId` | bytes32 | The voucher series ID | -| `voucherNonce` | uint256 | The specific voucher nonce | -| `transactionHash` | bytes32 | On-chain settlement transaction hash | -| `collectedAmount` | uint256 | Amount actually collected on-chain | -| `asset` | address | ERC-20 token contract address | -| `chainId` | uint256 | Network chain ID | -| `collectedAt` | uint64 | Collection timestamp | - -## Core Operations - -### 1. Voucher Storage - -**Operation**: `storeVoucher(voucher)` - -**Purpose**: Persist a new signed voucher received from a buyer. - -**Requirements**: -- MUST reject duplicate vouchers (same id + nonce combination) -- MUST validate all required fields are present -- SHOULD validate signature format (but not cryptographic validity) -- MUST return error if storage fails - -**Use Case**: When a seller receives a new payment voucher from a buyer, either for a new series or an aggregation of an existing series. - -### 2. Voucher Retrieval - -#### Single Voucher Lookup - -**Operation**: `getVoucher(id, nonce?)` - -**Purpose**: Retrieve a specific voucher or the latest in a series. - -**Behavior**: -- When `nonce` provided: Return exact voucher matching (id, nonce) -- When `nonce` omitted: Return voucher with highest nonce for the given id -- Return `null` if no matching voucher exists - -**Use Case**: Get the details of a voucher. - -#### Series Retrieval - -**Operation**: `getVoucherSeries(id, pagination)` - -**Purpose**: Retrieve all vouchers in a series for audit or history tracking. - -**Requirements**: -- MUST return vouchers sorted by nonce (descending - newest first) -- MUST support pagination with configurable limit and offset -- MUST return empty array for non-existent series - -**Pagination Options**: -- `limit`: The maximum number of vouchers to return -- `offset`: The offset of the first voucher to return - -**Use Case**: Display payment history, audit trail, or analyze aggregation patterns. - -#### Query-Based Retrieval - -**Operation**: `getVouchers(query, pagination)` - -**Purpose**: Find vouchers matching specific criteria. - -**Query Options**: -- `buyer`: Filter by buyer address -- `seller`: Filter by seller address -- `latest`: If true, return only highest nonce per series - -**Pagination Options**: -- `limit`: The maximum number of vouchers to return -- `offset`: The offset of the first voucher to return - -**Sorting**: -- Primary: By nonce (descending) -- Secondary: By timestamp (descending) - -**Use Case**: Dashboard views, account reconciliation, payment analytics. - -### 3. Available Voucher Discovery - -**Operation**: `getAvailableVoucher(buyer, seller)` - -**Purpose**: Find the most suitable voucher for aggregation in a new payment. - -**Selection Algorithm**: -1. Filter vouchers matching exact buyer and seller -2. For each series, select the voucher with highest nonce -3. Among selected vouchers, return the one with most recent timestamp -4. Return `null` if no vouchers match - -**Use Case**: When a seller needs to determine which existing voucher to use to aggregate new payments from a returning buyer. - -### 4. Settlement Recording - -**Operation**: `settleVoucher(voucher, txHash, amount)` - -**Purpose**: Record that a voucher has been collected on-chain. - -**Requirements**: -- MUST store the settlement record -- MUST associate with correct voucher (id, nonce) -- MUST record actual collected amount (may differ from voucher amount) -- SHOULD allow multiple collections for same voucher (partial settlements) - -**Use Case**: After successful on-chain collection, record the settlement for reconciliation and tracking. - -### 5. Collection History - -**Operation**: `getVoucherCollections(query, pagination)` - -**Purpose**: Retrieve settlement history for vouchers. - -**Query Options**: -- `id`: Filter by voucher series ID -- `nonce`: Filter by specific nonce (requires id) - -**Pagination Options**: -- `limit`: The maximum number of vouchers to return -- `offset`: The offset of the first voucher to return - -**Use Case**: Reconcile on-chain settlements with off-chain vouchers, audit payment flows. - -## Appendix - -### Reference Implementation - -The `InMemoryVoucherStore` class in the X402 TypeScript package provides a reference implementation suitable for development and testing. Production implementations should follow the same interface while adding appropriate persistence, scaling, and security features. \ No newline at end of file diff --git a/specs/x402-specification.md b/specs/x402-specification.md index bdcc9f04cb..62ec46899b 100644 --- a/specs/x402-specification.md +++ b/specs/x402-specification.md @@ -254,52 +254,10 @@ The facilitator performs the following verification steps: Settlement is performed by calling the `transferWithAuthorization` function on the ERC-20 contract with the signature and authorization parameters provided in the payment payload. -**6.2 Deferred Scheme** - -The "deferred" scheme enables micropayments through EIP-712 signed vouchers that aggregate off-chain before on-chain settlement. This approach is designed for scenarios where individual payment amounts are smaller than practical transaction costs. - -**6.2.1 EIP-712 Voucher Structure** - -The voucher follows the EIP-712 standard with the following structure: - -```javascript -const voucherTypes = { - Voucher: [ - { name: "id", type: "bytes32" }, - { name: "buyer", type: "address" }, - { name: "seller", type: "address" }, - { name: "valueAggregate", type: "uint256" }, - { name: "asset", type: "address" }, - { name: "timestamp", type: "uint64" }, - { name: "nonce", type: "uint256" }, - { name: "escrow", type: "address" }, - { name: "chainId", type: "uint256" }, - { name: "expiry", type: "uint64" }, - ], -}; -``` - -**6.2.2 Verification Steps** - -The facilitator performs the following verification steps: - -1. **Signature Validation**: Verify the EIP-712 voucher signature is valid -2. **Escrow Balance Check**: Confirm the buyer has sufficient deposited funds in the escrow contract -3. **Voucher Aggregation**: Validate nonce increment and value aggregation if building on existing voucher -4. **Expiry Validation**: Ensure the voucher has not expired -5. **Amount Validation**: Verify valueAggregate covers the required payment amount -6. **Collection Simulation**: Optionally simulate the escrow collection transaction - -**6.2.3 Settlement** - -Settlement occurs when the facilitator calls the `collect` function on the escrow contract with the voucher and signature. Multiple vouchers can be settled in a single transaction using `collectMany`. The escrow contract handles partial collection if insufficient funds are available. - **7. Facilitator Interface** The facilitator provides HTTP REST APIs for payment verification and settlement. This allows resource servers to delegate blockchain operations to trusted third parties or host the endpoints themselves. Note that while the core x402 protocol is transport-agnostic, facilitator APIs are currently standardized as HTTP endpoints. -The `deferred` scheme adds additional APIs to manage a facilitator voucher store for sellers. The specification for this can be found here: [Deferred Facilitator Spec](./schemes/deferred/scheme_deferred_evm_facilitator.md) - **7.1 POST /verify** Verifies a payment authorization without executing the transaction on the blockchain.